Google Analytics for WordPress by MonsterInsights - Version 6.0.0

Version Description

This is a major release. Please back up your site before upgrading.

=

Download this release

Release Info

Developer chriscct7
Plugin Icon 128x128 Google Analytics for WordPress by MonsterInsights
Version 6.0.0
Comparing to
See all releases

Code changes from version 5.5.4 to 6.0.0

Files changed (77) hide show
  1. README.md +219 -56
  2. admin/class-admin-assets.php +0 -101
  3. admin/class-admin-form.php +0 -338
  4. admin/class-admin-menu.php +0 -245
  5. admin/class-admin.php +0 -620
  6. admin/class-google-analytics.php +0 -365
  7. admin/class-googleanalytics-reporting.php +0 -156
  8. admin/dashboards/class-admin-dashboards-api-options.php +0 -89
  9. admin/dashboards/class-admin-dashboards-collector.php +0 -464
  10. admin/dashboards/class-admin-dashboards-data.php +0 -68
  11. admin/dashboards/class-admin-dashboards-display.php +0 -142
  12. admin/dashboards/class-admin-dashboards.php +0 -253
  13. admin/dashboards/drivers/class-admin-dashboards-driver-generate.php +0 -150
  14. admin/dashboards/drivers/class-admin-dashboards-driver.php +0 -83
  15. admin/dashboards/drivers/class-admin-dashboards-graph-generate.php +0 -154
  16. admin/dashboards/drivers/class-admin-dashboards-graph.php +0 -30
  17. admin/dashboards/drivers/class-admin-dashboards-table-generate.php +0 -74
  18. admin/dashboards/drivers/class-admin-dashboards-table.php +0 -30
  19. admin/dashboards/views/graph.php +0 -28
  20. admin/dashboards/views/table.php +0 -28
  21. admin/index.php +0 -4
  22. admin/pages/dashboard.php +0 -273
  23. admin/pages/extensions.php +0 -63
  24. admin/pages/settings.php +0 -188
  25. admin/views/content-footer.php +0 -17
  26. admin/views/content_head.php +0 -2
  27. assets/css/admin.css +540 -0
  28. assets/css/admin.min.css +1 -0
  29. assets/css/font-awesome/font-awesome.css +2199 -0
  30. assets/css/font-awesome/font-awesome.min.css +4 -0
  31. assets/css/images/index.php +4 -0
  32. assets/css/images/logo.png +0 -0
  33. assets/css/images/logo@2x.png +0 -0
  34. assets/css/images/mascot.png +0 -0
  35. assets/css/images/mascot@2x.png +0 -0
  36. assets/css/images/menu-icon.png +0 -0
  37. assets/css/images/menu-icon@2x.png +0 -0
  38. assets/css/images/monsterinsights.png +0 -0
  39. assets/css/images/waves.png +0 -0
  40. assets/css/images/waves@x2.png +0 -0
  41. assets/css/index.php +3 -3
  42. assets/css/jvectormap/jquery-jvectormap-2.0.3.css +135 -0
  43. assets/css/select2/index.php +4 -0
  44. assets/css/select2/select2.css +484 -0
  45. assets/css/select2/select2.min.css +1 -0
  46. assets/css/yoast_ga_admin_dashboard.css +0 -76
  47. assets/css/yoast_ga_admin_dashboard.min.css +0 -1
  48. assets/css/yoast_ga_styles.css +0 -232
  49. assets/css/yoast_ga_styles.min.css +0 -1
  50. assets/dependencies/chosen/chosen-sprite.png +0 -0
  51. assets/dependencies/chosen/chosen-sprite@2x.png +0 -0
  52. assets/dependencies/chosen/chosen.css +0 -437
  53. assets/dependencies/chosen/chosen.jquery.min.js +0 -2
  54. assets/dependencies/chosen/chosen.min.css +0 -3
  55. assets/dependencies/chosen/index.php +0 -4
  56. assets/dependencies/datatables/css/jquery.dataTables.css +0 -450
  57. assets/dependencies/datatables/css/jquery.dataTables.min.css +0 -1
  58. assets/dependencies/datatables/images/Sorting icons.psd +0 -0
  59. assets/dependencies/datatables/images/back_disabled.png +0 -0
  60. assets/dependencies/datatables/images/back_enabled.png +0 -0
  61. assets/dependencies/datatables/images/back_enabled_hover.png +0 -0
  62. assets/dependencies/datatables/images/favicon.ico +0 -0
  63. assets/dependencies/datatables/images/forward_disabled.png +0 -0
  64. assets/dependencies/datatables/images/forward_enabled.png +0 -0
  65. assets/dependencies/datatables/images/forward_enabled_hover.png +0 -0
  66. assets/dependencies/datatables/images/sort_asc.png +0 -0
  67. assets/dependencies/datatables/images/sort_asc_disabled.png +0 -0
  68. assets/dependencies/datatables/images/sort_both.png +0 -0
  69. assets/dependencies/datatables/images/sort_desc.png +0 -0
  70. assets/dependencies/datatables/images/sort_desc_disabled.png +0 -0
  71. assets/dependencies/datatables/js/jquery.dataTables.js +0 -15095
  72. assets/dependencies/datatables/js/jquery.dataTables.min.js +0 -163
  73. assets/dependencies/focusable/focus-element-overlay.min.js +0 -1
  74. assets/dependencies/index.php +0 -4
  75. assets/dependencies/qtip/index.php +0 -4
  76. assets/dependencies/qtip/jquery.qtip.min.js +0 -21
  77. assets/dependencies/rickshaw/d3.v3.min.js +0 -1
README.md CHANGED
@@ -1,56 +1,219 @@
1
- Google Analytics for WordPress
2
- ==============================
3
-
4
- [![Build Status](https://api.travis-ci.org/Yoast/google-analytics-for-wordpress.png?branch=master)](https://travis-ci.org/Yoast/google-analytics-for-wordpress) [![Code Climate](https://codeclimate.com/repos/54523bb669568068b8093b43/badges/04d59b3dc67a0c7ff8ab/gpa.svg)](https://codeclimate.com/repos/54523bb669568068b8093b43/feed)
5
-
6
- Add Google Analytics to WordPress and be able to use all the powerful functions Google Analytics offers!
7
-
8
-
9
- Welcome to the Google Analytics for WordPress Github repository
10
- ----------------------------------------------
11
-
12
- While the documentation for the [Google Analytics for WordPress plugin](http://www.monsterinsights.com/docs/) can be found on monsterinsights.com, here
13
- you can browse the source of the project, find and discuss open issues and even
14
- [contribute yourself](https://github.com/awesomemotive/google-analytics-for-wordpress/blob/master/CONTRIBUTING.md).
15
-
16
- Installation
17
- ------------
18
-
19
- Here's a [guide on how to install Google Analytics for WordPress in your WordPress site](http://www.monsterinsights.com/docs/getting-started/).
20
-
21
- If you want to run the Git version for development though, you can set it up with [Composer](https://getcomposer.org/):
22
-
23
- ```bash
24
- composer create-project awesomemotive/google-analytics:dev-trunk --prefer-source --keep-vcs
25
- ```
26
-
27
- This will download the latest development version of Google Analytics for WordPress by MonsterInsights. While this version is usually stable,
28
- it is not recommended for use in a production environment.
29
-
30
- Bugs
31
- ----
32
- If you find an issue, [let us know here](https://github.com/monsterinsights/google-analytics-for-wordpress/issues/new)!
33
-
34
- Please report security issues privately to **support@monsterinsights.com**.
35
-
36
- Support
37
- -------
38
- This is a developer's portal for Google Analytics for WordPress by MonsterInsights and should not be used for support. Please visit the
39
- [support forums](http://wordpress.org/support/plugin/google-analytics-for-wordpress).
40
-
41
- Contributions
42
- -------------
43
- Anyone is welcome to contribute to Google Analytics for WordPress. Please
44
- [read the guidelines](https://github.com/awesomemotive/google-analytics-for-wordpress/blob/master/CONTRIBUTING.md) for contributing to this
45
- repository.
46
-
47
- There are various ways you can contribute:
48
-
49
- * [Raise an issue](https://github.com/awesomemotive/google-analytics-for-wordpress/issues) on GitHub.
50
- * Send us a Pull Request with your bug fixes and/or new features.
51
- * Provide feedback and [suggestions on enhancements](https://github.com/awesomemotive/google-analytics-for-wordpress/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open).
52
-
53
- Changelog
54
- =========
55
-
56
- Please see readme.txt for the changelog.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [MonsterInsights](https://www.monsterinsights.com) #
2
+ The best Google Analytics Integration for WordPress. Period.<br />
3
+ ![Plugin Version](https://img.shields.io/wordpress/plugin/v/google-analytics-for-wordpress.svg?maxAge=2592000)
4
+ ![Total Downloads](https://img.shields.io/wordpress/plugin/dt/google-analytics-for-wordpress.svg?maxAge=2592000)
5
+ ![WordPress Compatibility](https://img.shields.io/wordpress/v/google-analytics-for-wordpress.svg?maxAge=2592000)
6
+ [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.2-8892BF.svg?style=flat-square)](https://php.net/)
7
+ [![Build Status](https://img.shields.io/travis/awesomemotive/google-analytics-for-wordpress/master.svg?maxAge=2592000)](https://travis-ci.org/awesomemotive/google-analytics-for-wordpress)
8
+ [![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/awesomemotive/google-analytics-for-wordpress.svg)](https://scrutinizer-ci.com/gawesomemotive/google-analytics-for-wordpress/?branch=master)
9
+ [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/awesomemotive/google-analytics-for-wordpress.svg?maxAge=2592000)](https://scrutinizer-ci.com/g/awesomemotive/google-analytics-for-wordpress/?branch=master)
10
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/d7e64d1841794c249ea74f1e0e81a0e2)](https://www.codacy.com/app/chriscct7/google-analytics-for-wordpress?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=awesomemotive/google-analytics-for-wordpress&amp;utm_campaign=Badge_Grade)
11
+ [![License](https://img.shields.io/badge/license-GPL--2.0%2B-red.svg)](https://github.com/awesomemotive/google-analytics-for-wordpress/blob/master/license.txt)
12
+
13
+ ## Contributions ##
14
+ Anyone is welcome to contribute to MonsterInsights. Please read the [guidelines for contributing](https://github.com/awesomemotive/google-analytics-for-wordpress/blob/master/CONTRIBUTING.md) to this repository.
15
+
16
+ There are various ways you can contribute:
17
+
18
+ 1. Raise an [Issue](https://github.com/awesomemotive/google-analytics-for-wordpress/issues) on GitHub
19
+ 2. Send us a Pull Request with your bug fixes and/or new features
20
+ 3. Provide feedback and suggestions on [enhancements](https://github.com/awesomemotive/google-analytics-for-wordpress/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open)
21
+
22
+ ## Bugs ##
23
+ If you find an issue, let us know [here](https://github.com/awesomemotive/google-analytics-for-wordpress/issues?state=open)!
24
+
25
+ ## Support ##
26
+ This is a developer's portal for Google Analytics for WordPress by MonsterInsights and should not be used for support.
27
+
28
+ For the lite version please use the wordpress.org [support forums](http://wordpress.org/support/plugin/google-analytics-for-wordpress).
29
+
30
+ For users of the pro version, please use the support form, located on the Support tab of the My Account page of our website (note: you must be logged in & have
31
+ an active license to use this form).
32
+
33
+ Please report security issues to support@monsterinsights.com
34
+
35
+ ## Backwards Compatibility Guidelines for Developers ##
36
+ Note all functionality on the admin side of the plugin, including any php/js/css functions, class names, files (or filenames), hooks or otherwise will not be garunteed backwards compatibility as a general rule. Our admin code is subject to change at any time without warning. As MonsterInsights is a frontend focused plugin, we're not too sure why you'd be building stuff with our backend code anyways. If you for some reason do need to use our backend code (anything located in admin or enqueued only in admin), please contact us with your usecase so we can adjust this policy and ensure your code will not break in the future.
37
+
38
+ For the frontend, we will not garuntee that the JS output will always be the same, nor can we, as we will adjust it over time to ensure continued Google Analytics compatibility and add features. However, we will garuntee the backwards compatibility of any hooks (filters or actions) found exclusively in the `lite/includes/frontend`, `pro/includes/frontend`, and `includes/frontend` directories to the best of our abilities. These hooks are documented as such. Any sort of future breakage will be announced well in advance of any changes, and we'll try to never break anyone's use of these hooks.
39
+
40
+ ## Code Styling Documentation ##
41
+
42
+ MonsterInsights adheres to the WordPress core PHP standard with a couple deviations noted below. See https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/ for information on documenting using this standard.
43
+
44
+ ### Deviations ###
45
+
46
+ - [Use `elseif`, not `else if`](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#use-elseif-not-else-if)
47
+ - In MonsterInsights, use `else if` as we do not permit use of the colon form of `if else`, rendering Core's reason for this rule null. Colon forms of `if else` are harder for text editors such as Sublime Text to parse the opening and closing of conditional logic, and thus are not permitted.
48
+ - Avoid regular expressions wherever possible
49
+ - Regular expressions make it more difficult for new contributors to contribute. Thus whenever possible, regular expressions should be avoided.
50
+ - [Yoda Conditions](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#yoda-conditions)
51
+ - Code should never be written where a variable is being non-strictly compared to `true` or `false`. Use the appropriate way of writing the if statement. `if ( true == $var )` is equivolent to `if ( $var )` and the latter is much easier to read. However when strict comparison is required (`===`), one should use `if ( true === $var )`.
52
+
53
+ ### Additions ###
54
+
55
+ - Required: Functions should be unit testable, documented and unit-tested
56
+ - When submitting new functions, ensure the functions are easily testable by PHPUnit where applicable. If altering existing functions, adjust and add/remove unit tests and documentation covering the function where applicable. If you're adding/editing a function in a class, make sure to add `@access {private|public|protected}`
57
+ - Required: Code should be formatted using tabs, set to size of 4 spaces
58
+ - 4 spaces per tab is the universally accepted default tab size. Tabs are easier to read through in most editors. Additionally, they take up less file space than 4 spaces.
59
+ - Required: Filter and function names should use underscores, not dashes
60
+ - For consistency, all filter and functions should use underscores not dashes or CamelCasing when seperating words. Additionally, all filter and (functions not in a class) names should be preceeded by `monsterinsights_`. The only exception to this is filters that need to be pro or lite only, in which case they should be proceeded by `monsterinsights_pro_` and `monsterinsights_lite_` respectively. Functions in a class should not be preceeded by `monsterinsights_`.
61
+ - Required: Hooks tied to a function not within a class, will be tied to the function after the end of the function's declaration
62
+ - Since MonsterInsights requires all functions have a function docbloc immediately preceeding the declaration of a function, to make it easier to locate hooks tied to a function, the `add_action` or `add_filter` call(s) to a function shall be placed immediately after the end of a function declaration. For functions in classes, this rule does not apply as it is impossible to do this.
63
+ - Recommended: Use pre-increments (`++i`) instead of post-increments (`i++`)
64
+ - The former is more performant as it does not require a copy of the variable to be made. This rule is not strictly enforced, and where it detracts from the readability or simplicity of code, it should be ignored.
65
+ - Recommended: Where possible avoid stored data changes
66
+ - This plugin has a lot of active installs. As such, whereever possible, we should try to avoid requiring an upgrade routine to convert stored data. Having a routine that adds data to make something more performant is fine as long as it either falls back to existing data, a smart default, or stops execution (in a controlled manner).
67
+
68
+ ## Language Translations, Textdomains, and Internationalization ##
69
+
70
+ MonsterInsights is translation ready. Thanks to an extensive team of .org translators, much of the plugin is available translated into a wide variety of languages.
71
+
72
+ ### What Textdomain to Use ##
73
+
74
+ In googleanalytics-premium.php and in the /pro/ folder only use `ga-premium`. Everywhere else use `google-analytics-for-wordpress`.
75
+
76
+ MonsterInsights Lite uses WordPress.org provided translation files. MonsterInsights Pro loads the Lite translation files for files shared with Lite, and also loads Pro-only translation files for the Pro-only files. These files are created automatically from Pro translations. The latest copy of these files are pulled down and deployed with each Pro release.
77
+
78
+ ### How To Contribute Translations ###
79
+
80
+ Via the WordPress.org translation system located [here](https://www.wordpress.org/plugins/google-analytics-for-wordpress/translations/).
81
+
82
+ ### I've found a non-translatable string that a user can see. What should I do? ###
83
+
84
+ Please open a [issue](https://github.com/awesomemotive/google-analytics-for-wordpress/issues) for it.
85
+
86
+ ## Documentation ##
87
+
88
+ MonsterInsights has adopted the WordPress core PHP documentation standard. See https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/php/ for information on documenting using this standard.
89
+
90
+ MonsterInsights is compatible with both PHPDocumentor2 and PHPDox.
91
+
92
+ Soon, you'll also be able to build phpDocumenter and PHPDox documentation for MonsterInsights by running `robo documentation`.
93
+
94
+ In the meantime you can run `php phpDocumentor.phar run` and `php phpdox.phar` respectively.
95
+
96
+ Be aware in order to make the graphs in PHPDocumentor2 you must have Graphviz installed.
97
+
98
+ ## Automation ##
99
+
100
+ A project goal of MonsterInsights, is to embrace automation whenever possible.
101
+
102
+ The MonsterInsights project taskrunner standard is Robo, and tasks for this project can be found in RoboFile.php (not available to public), and executed via:
103
+ robo {command}
104
+
105
+ Some goals of the project moving forward is to allow for documentation of MonsterInsights, as well as releases of MonsterInsights with as minimal effort required.
106
+
107
+ The MonsterInsights project dependency management system is Composer. Please make sure you don't accidentily override our composer file in your PRs.
108
+
109
+ ## PHP Unit Testing ##
110
+
111
+ A goal of this project is to make all functionality unit tested.
112
+
113
+ The project goal is to become code covered. Over time, we will release our internal unit tests to the public repo.
114
+
115
+ This project uses Travis-CI Free & Pro for continous integration on push and pull requests.
116
+
117
+ Code coverage analysis, as well as general project code quality is available from Codacy.
118
+
119
+ Perhaps you'd like to run our unit tests locally?
120
+
121
+ Awesome, we offer 3 options for doing that:
122
+
123
+ - PHPCI
124
+ - JoliCI (note: there's a bug that prevents this from working in Windows envs atm caused by a TLS verified call in dependency docker-php caused by a bug in openssl (which isn't changeable on WAMP). Ref: https://github.com/stage1/docker-php/issues/140 )
125
+ - Standard PHPUnit
126
+
127
+ JoliCI additionally allows you to parse and run the Travis-CI suite locally using Docker
128
+
129
+ ## Development Checkout Procedure ##
130
+
131
+ `php composer.phar install`
132
+
133
+ or soon, the recommended way will be
134
+
135
+ `php robo.phar setup`
136
+
137
+ ## Constants ##
138
+
139
+ The following constants can be defined in a wp-config file to allow for sections of MonsterInsights to be turned on and off across an installation base (and also for unit testing)
140
+
141
+ ### Both Pro & Lite ###
142
+
143
+ Plugin defined:
144
+ - `MONSTERINSIGHTS_VERSION`
145
+ - The version of pro/lite installed
146
+ - `MONSTERINSIGHTS_PLUGIN_NAME`
147
+ - The name of the plugin
148
+ - `MONSTERINSIGHTS_PLUGIN_SLUG`
149
+ - The slug of this plugin
150
+ - `MONSTERINSIGHTS_PLUGIN_FILE`
151
+ - The name of this file
152
+ - `MONSTERINSIGHTS_PLUGIN_DIR`
153
+ - Path to the MI base folder
154
+ - `MONSTERINSIGHTS_PLUGIN_URL`
155
+ - URL to the MI base folder
156
+
157
+ User defined:
158
+ - `MONSTERINSIGHTS_LICENSE_KEY`
159
+ - MonsterInsights license key to use
160
+ - `MONSTERINSIGHTS_FORCE_ACTIVATION`
161
+ - Override the WP version activation check. Use at your own risk.
162
+ - `MONSTERINSIGHTS_AIRPLANE_MODE`
163
+ - For future use. Currently does nothing. Useful for local site testing.
164
+ - `MONSTERINSIGHTS_GA_UA`
165
+ - Don't use oAuth or the wizard, but hardcode to use UA. Note, this will not allow backend reports to work. You can also use the filter `monsterinsights_ga_ua`.
166
+ - `MONSTERINSIGHTS_MULTISITE_GA_UA`. See UA priority rules below.
167
+ - You can use this constant to force the same the same UA for all subsites of an MS install. Note, this will not allow backend reports to work. See UA priority rules below.
168
+ - `MONSTERINSIGHTS_DEBUG_MODE`
169
+ - Enables analytics.js and events tracking debug mode. Sets asset version to time(). In future, turns on logging to file for logging class. Available to turn on in backend via debug_mode setting.
170
+ - `MONSTERINSIGHTS_SHAREASALE_ID`
171
+ - If you want to bundle MonsterInsights with a theme, you can use this constant to ensure you get affiliate credit for any conversions.
172
+
173
+ ### Lite Only ###
174
+ - `MONSTERINSIGHTS_LITE_VERSION`
175
+ - The version of lite installed
176
+
177
+ ### Pro Only ###
178
+ - `MONSTERINSIGHTS_PRO_VERSION`
179
+ - The version of pro installed
180
+
181
+ ### Legacy Constants ###
182
+
183
+ We declare these for code that relies on old constants. Please upgrade your code to use the new constants.
184
+
185
+ - `GA_YOAST_PREMIUM_VERSION`
186
+ - Use `MONSTERINSIGHTS_PRO_VERSION` instead.
187
+ - `GAWP_VERSION`
188
+ - Use `MONSTERINSIGHTS_VERSION` instead.
189
+ - `GAWP_FILE`
190
+ - Use `MONSTERINSIGHTS_PLUGIN_FILE` instead.
191
+ - `GAWP_PATH`
192
+ - Use `MONSTERINSIGHTS_PLUGIN_DIR` instead.
193
+ - `GAWP_URL`
194
+ - Use `MONSTERINSIGHTS_PLUGIN_URL` instead.
195
+
196
+
197
+ ## Google Analytics UA Priority Rules
198
+ These rules dictate which Google Analytics UA code is used.
199
+ The order of priority is as follows (top of list has most priority):
200
+
201
+ - `monsterinsights_ga_ua` filter
202
+ - MonsterInsights per site settings for manual UA or oAuth retrieved UA
203
+ - Note, these settings are hidden when MONSTERINSIGHTS_GA_UA is defined
204
+ - `MONSTERINSIGHTS_GA_UA` constant
205
+ - `MONSTERINSIGHTS_MS_GA_UA` constant (Multisite use only)
206
+
207
+
208
+ As a result of this order of priority, on MS installs you can use the `MONSTERINSIGHTS_MS_GA_UA` constant to
209
+ set the default UA for all of the subsites of an MS install, and then override that on a subsite basis using either
210
+ the UI in the settings panel, the `MONSTERINSIGHTS_GA_UA` constant or the `monsterinsights_ga_ua` filter.
211
+
212
+ Let's say you run a really large MS install, like for a university, and all of your sites are {sitename}.mysite.com or
213
+ mysite.com/{example}/. In this case, you can quickly deploy MI for your entire network by network activating MonsterInsights
214
+ and using the `MONSTERINSIGHTS_MS_GA_UA` constant. This is a new feature, available starting with MonsterInsights 6.0.0.
215
+
216
+ Also, since you can now filter each option value retrieved (via the filter in the Option's class's get_option() function ),
217
+ you can even set the values used for each setting. If you want, you can disable access to site users by setting the menu capability for MonsterInsights
218
+ to a custom or non-existant capability, and as a result run MonsterInsights without any user even needing to see the WordPress backend for
219
+ MonsterInsights.
admin/class-admin-assets.php DELETED
@@ -1,101 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * This class is for the backend
8
- */
9
- class Yoast_GA_Admin_Assets {
10
-
11
- /**
12
- * Add the scripts to the admin head
13
- */
14
- public static function enqueue_scripts() {
15
- wp_enqueue_script( 'yoast_focusable', self::get_asset_path( 'assets/dependencies/focusable/focus-element-overlay.min.js' ), array( 'jquery' ), false );
16
-
17
- wp_enqueue_script( 'yoast_ga_admin', self::get_asset_path( 'assets/js/yoast_ga_admin' ) . self::file_ext( '.js' ), array( 'jquery', 'yoast_focusable' ), GAWP_VERSION );
18
-
19
- // Enqueue the qtip js file
20
- wp_enqueue_script( 'jquery-qtip', self::get_asset_path( 'assets/dependencies/qtip/jquery.qtip.min.js' ), array( 'jquery' ), '1.0.0-RC3', true );
21
-
22
- // Enqueue the chosen js file
23
- wp_enqueue_script( 'chosen_js', self::get_asset_path( 'assets/dependencies/chosen/chosen.jquery.min.js' ), array(), GAWP_VERSION, true );
24
- }
25
-
26
- /**
27
- * Add the styles in the admin head
28
- */
29
- public static function enqueue_styles() {
30
- wp_enqueue_style( 'yoast_ga_styles', self::get_asset_path( 'assets/css/yoast_ga_styles' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
31
- }
32
-
33
- /**
34
- * Enqueues the settings page specific styles
35
- */
36
- public static function enqueue_settings_styles() {
37
- // Enqueue the chosen css file
38
- wp_enqueue_style( 'chosen_css', self::get_asset_path( 'assets/dependencies/chosen/chosen' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
39
- }
40
-
41
- /**
42
- * Loading the assets for dashboard
43
- */
44
- public static function enqueue_dashboard_assets() {
45
-
46
- wp_enqueue_script( 'ga-admin-dashboard', self::get_asset_path( 'assets/js/yoast_ga_admin_dashboard' ) . self::file_ext( '.js' ), array(), GAWP_VERSION );
47
- wp_enqueue_style( 'ga-admin-dashboard-css', self::get_asset_path( 'assets/css/yoast_ga_admin_dashboard' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
48
-
49
- // Enqueue the d3 js file
50
- wp_enqueue_script( 'd3_js', self::get_asset_path( 'assets/dependencies/rickshaw/d3.v3.min.js' ), array(), GAWP_VERSION, true );
51
-
52
- // Enqueue the ricksaw js file
53
- wp_enqueue_script( 'rickshaw_js', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.js' ), array(), GAWP_VERSION, true );
54
-
55
- // Enqueue the rickshaw css
56
- wp_enqueue_style( 'rickshaw_css', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.css' ), array(), GAWP_VERSION );
57
-
58
- // Enqueue the datatables js file
59
- wp_enqueue_script( 'datatables_js', self::get_asset_path( 'assets/dependencies/datatables/js/jquery.dataTables.min.js' ), array(), GAWP_VERSION, true );
60
-
61
- // Enqueue the datatables css
62
- wp_enqueue_style( 'datatables_css', self::get_asset_path( 'assets/dependencies/datatables/css/jquery.dataTables.min.css' ), array(), GAWP_VERSION );
63
-
64
- Yoast_GA_Dashboards::get_instance()->add_dashboard_js_translations();
65
- }
66
-
67
- /**
68
- * Getting the full path to given $asset
69
- *
70
- * @param string $asset
71
- *
72
- * @return string
73
- */
74
- public static function get_asset_path( $asset ) {
75
- static $plugin_directory;
76
-
77
- if ( $plugin_directory == null ) {
78
- $plugin_directory = plugin_dir_url( GAWP_FILE );
79
- }
80
-
81
- $return = $plugin_directory . $asset;
82
-
83
- return $return;
84
- }
85
-
86
- /**
87
- * Check whether we can include the minified version or not
88
- *
89
- * @param string $ext
90
- *
91
- * @return string
92
- */
93
- private static function file_ext( $ext ) {
94
- if ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) {
95
- $ext = '.min' . $ext;
96
- }
97
-
98
- return $ext;
99
- }
100
-
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-admin-form.php DELETED
@@ -1,338 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * This class is for the backend
8
- */
9
- class Yoast_GA_Admin_Form {
10
-
11
- /**
12
- * @var string $form_namespace
13
- */
14
- private static $form_namespace;
15
-
16
- /**
17
- * Create a form element to init a form
18
- *
19
- * @param string $namespace
20
- *
21
- * @return string
22
- */
23
- public static function create_form( $namespace ) {
24
- self::$form_namespace = $namespace;
25
-
26
- $action = admin_url( 'admin.php' );
27
- if ( isset( $_GET['page'] ) ) {
28
- $action .= '?page=' . $_GET['page'];
29
- }
30
-
31
- return '<form action="' . $action . '" method="post" id="yoast-ga-form-' . self::$form_namespace . '" class="yoast_ga_form">' . wp_nonce_field( 'save_settings', 'yoast_ga_nonce', null, false );
32
- }
33
-
34
-
35
- /**
36
- * Return the form end tag and the submit button
37
- *
38
- * @param string $button_label
39
- * @param string $name
40
- * @param string $onclick
41
- *
42
- * @return null|string
43
- */
44
- public static function end_form( $button_label = null, $name = 'submit', $onclick = null ) {
45
- if ( $button_label === null ) {
46
- $button_label = __( 'Save changes', 'google-analytics-for-wordpress' );
47
- }
48
-
49
- $output = null;
50
- $output .= '<div class="ga-form ga-form-input">';
51
- $output .= '<input type="submit" name="ga-form-' . $name . '" value="' . $button_label . '" class="button button-primary ga-form-submit" id="yoast-ga-form-submit-' . self::$form_namespace . '"';
52
- if ( ! is_null( $onclick ) ) {
53
- $output .= ' onclick="' . $onclick . '"';
54
- }
55
- $output .= ' />';
56
- $output .= '</div></form>';
57
-
58
- return $output;
59
- }
60
-
61
-
62
- /**
63
- * Create a input form element with our labels and wrap them
64
- *
65
- * @param string $type
66
- * @param null|string $title
67
- * @param null|string $name
68
- * @param null|string $text_label
69
- * @param null|string $description
70
- *
71
- * @return null|string
72
- */
73
- public static function input( $type = 'text', $title = null, $name = null, $text_label = null, $description = null ) {
74
- $input = null;
75
- $id = str_replace( '[', '-', $name );
76
- $id = str_replace( ']', '', $id );
77
-
78
- $input_value = self::get_formfield_from_options( $name );
79
-
80
- $input .= '<div class="ga-form ga-form-input">';
81
- if ( ! is_null( $title ) ) {
82
- $input .= self::label( $id, $title, $type );
83
- }
84
-
85
- $attributes = array(
86
- 'type' => $type,
87
- 'id' => 'yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '',
88
- 'name' => $name,
89
- 'class' => 'ga-form ga-form-' . $type . ' ',
90
- );
91
-
92
- if ( $type == 'checkbox' ) {
93
- $attributes['value'] = '1';
94
-
95
- if ( $input_value == 1 ) {
96
- $attributes['checked'] = 'checked';
97
- }
98
- }
99
- else {
100
- $attributes['value'] = esc_attr( stripslashes( $input_value ) );
101
- }
102
-
103
- $input .= '<input ' . self::parse_attributes( $attributes ) . ' />';
104
-
105
- // If we get a description, append it to this select field in a new row
106
- if ( ! is_null( $description ) ) {
107
- $input .= self::show_help( $id, $description );
108
- }
109
-
110
- if ( ! is_null( $text_label ) ) {
111
- $input .= '<label class="ga-form ga-form-' . $type . '-label" id="yoast-ga-form-label-' . $type . '-textlabel-' . self::$form_namespace . '-' . $id . '" for="yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $text_label . '</label>';
112
- }
113
-
114
- $input .= '</div>';
115
-
116
- return $input;
117
- }
118
-
119
- /**
120
- * Generate a select box
121
- *
122
- * @param string $title
123
- * @param string $name
124
- * @param array $values
125
- * @param null|string $description
126
- * @param bool $multiple
127
- * @param string $empty_text
128
- *
129
- * @return null|string
130
- */
131
- public static function select( $title, $name, $values, $description = null, $multiple = false, $empty_text = null ) {
132
- $select = null;
133
- $id = str_replace( '[', '-', $name );
134
- $id = str_replace( ']', '', $id );
135
-
136
- $select .= '<div class="ga-form ga-form-input">';
137
- if ( ! is_null( $title ) ) {
138
- $select .= self::label( $id, $title, 'select' ); // '<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
139
- }
140
-
141
- if ( $multiple ) {
142
- $select .= '<select multiple name="' . $name . '[]" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '" class="ga-multiple">';
143
- }
144
- else {
145
- $select .= '<select data-placeholder="' . $empty_text . '" name="' . $name . '" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '">';
146
- if ( ! is_null( $empty_text ) ) {
147
- $select .= '<option></option>';
148
- }
149
- }
150
- if ( count( $values ) >= 1 ) {
151
- $select_value = self::get_formfield_from_options( $name );
152
-
153
- foreach ( $values as $optgroup => $value ) {
154
- if ( ! empty( $value['items'] ) ) {
155
- $select .= self::create_optgroup( $optgroup, $value, $select_value );
156
- }
157
- else {
158
- $select .= self::option( $select_value, $value );
159
- }
160
- }
161
- }
162
- $select .= '</select>';
163
-
164
- if ( ! is_null( $description ) ) {
165
- $select .= self::show_help( $id, $description );
166
- }
167
-
168
- $select .= '</div>';
169
-
170
- return $select;
171
- }
172
-
173
-
174
- /**
175
- * Generate a textarea field
176
- *
177
- * @param string $title
178
- * @param string $name
179
- * @param null|string $description
180
- *
181
- * @return null|string
182
- */
183
- public static function textarea( $title, $name, $description = null ) {
184
- $text = null;
185
- $id = Yoast_GA_Options::instance()->option_prefix . '_' . $name;
186
-
187
- $textarea_value = self::get_formfield_from_options( $name );
188
-
189
- $text .= '<div class="ga-form ga-form-input">';
190
-
191
- if ( ! is_null( $title ) ) {
192
- $text .= '<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . __( $title, 'google-analytics-for-wordpress' ) . ':</label>';
193
- }
194
-
195
- $text .= '<textarea rows="5" cols="60" name="' . $name . '" id="yoast-ga-form-textarea-' . self::$form_namespace . '-' . $id . '">' . stripslashes( $textarea_value ) . '</textarea>';
196
-
197
- if ( ! is_null( $description ) ) {
198
- $text .= self::show_help( $id, $description );
199
- }
200
-
201
- $text .= '</div>';
202
-
203
- return $text;
204
- }
205
-
206
- /**
207
- * Parsing a option string for select
208
- *
209
- * @param string $select_value
210
- * @param string $value
211
- *
212
- * @return string
213
- */
214
- private static function option( $select_value, $value ) {
215
-
216
- if ( is_array( $select_value ) ) {
217
- if ( in_array( esc_attr( $value['id'] ), $select_value ) ) {
218
- return '<option value="' . esc_attr( $value['id'] ) . '" selected="selected">' . esc_attr( stripslashes( $value['name'] ) ) . '</option>';
219
- }
220
- else {
221
- return '<option value="' . esc_attr( $value['id'] ) . '">' . esc_attr( stripslashes( $value['name'] ) ) . '</option>';
222
- }
223
- }
224
- else {
225
- return '<option value="' . esc_attr( $value['id'] ) . '" ' . selected( $select_value, $value['id'], false ) . '>' . esc_attr( stripslashes( $value['name'] ) ) . '</option>';
226
- }
227
- }
228
-
229
-
230
- /**
231
- * Show a question mark with help
232
- *
233
- * @param string $id
234
- * @param string $description
235
- *
236
- * @return string
237
- */
238
- public static function show_help( $id, $description ) {
239
- $help = '<img src="' . plugins_url( 'assets/img/question-mark.png', GAWP_FILE ) . '" class="alignleft yoast_help" id="' . esc_attr( $id . 'help' ) . '" alt="' . esc_attr( $description ) . '" />';
240
-
241
- return $help;
242
- }
243
-
244
-
245
- /**
246
- * Will parse the optgroups.
247
- *
248
- * @param array $values
249
- *
250
- * @return array
251
- */
252
- public static function parse_optgroups( $values ) {
253
- $optgroups = array();
254
- foreach ( $values as $key => $value ) {
255
- foreach ( $value['items'] as $subitem ) {
256
- $optgroups[ $subitem['name'] ]['items'] = $subitem['items'];
257
- }
258
- }
259
-
260
- return $optgroups;
261
- }
262
-
263
- /**
264
- * Creates a label
265
- *
266
- * @param string $id
267
- * @param string $title
268
- * @param string $type
269
- *
270
- * @return string
271
- */
272
- private static function label( $id, $title, $type ) {
273
- return '<label for="' . 'yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '" class="ga-form ga-form-' . $type . '-label ga-form-label-left" id="yoast-ga-form-label-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
274
- }
275
-
276
- /**
277
- * Creates a optgroup with the items. If items contain items it will create a nested optgroup
278
- *
279
- * @param string $optgroup
280
- * @param array $value
281
- * @param array $select_value
282
- *
283
- * @return string
284
- */
285
- private static function create_optgroup( $optgroup, $value, $select_value ) {
286
- $optgroup = '<optgroup label="' . esc_attr( $optgroup ) . '">';
287
-
288
- foreach ( $value['items'] as $option ) {
289
- if ( ! empty( $option['items'] ) ) {
290
-
291
- $optgroup .= self::create_optgroup( esc_attr( $option['name'] ), $option, $select_value );
292
- }
293
- else {
294
- $optgroup .= self::option( $select_value, $option );
295
- }
296
- }
297
-
298
- $optgroup .= '</optgroup>';
299
-
300
- return $optgroup;
301
- }
302
-
303
-
304
- /**
305
- * Getting the value from the option, if it doesn't exist return empty string
306
- *
307
- * @param string $name
308
- *
309
- * @return string
310
- */
311
- private static function get_formfield_from_options( $name ) {
312
- static $options;
313
-
314
- if ( $options === null ) {
315
- $options = Yoast_GA_Options::instance()->get_options();
316
- }
317
-
318
- // Catch a notice if the option doesn't exist, yet
319
- return ( isset( $options[ $name ] ) ) ? $options[ $name ] : '';
320
- }
321
-
322
- /**
323
- * Parsing given array with attributes as an attribute string
324
- *
325
- * @param array $attributes_to_parse
326
- *
327
- * @return string
328
- */
329
- private static function parse_attributes( $attributes_to_parse ) {
330
- $parsed_attributes = '';
331
- foreach ( $attributes_to_parse as $attribute_name => $attribute_value ) {
332
- $parsed_attributes .= $attribute_name . '="' . $attribute_value . '" ';
333
- }
334
-
335
- return trim( $parsed_attributes );
336
- }
337
-
338
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-admin-menu.php DELETED
@@ -1,245 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * This class is for the backend, extendable for all child classes
8
- */
9
- class Yoast_GA_Admin_Menu {
10
-
11
- /**
12
- * @var object $target_object The property used for storing target object (class admin)
13
- */
14
- private $target_object;
15
-
16
- /**
17
- * @var boolean $dashboard_disabled The dashboards disabled bool
18
- */
19
- private $dashboards_disabled;
20
-
21
- /**
22
- * The parent slug for the submenu items based on if the dashboards are disabled or not.
23
- *
24
- * @var string
25
- */
26
- private $parent_slug;
27
-
28
- /**
29
- * Setting the target_object and adding actions
30
- *
31
- * @param object $target_object
32
- */
33
- public function __construct( $target_object ) {
34
-
35
- $this->target_object = $target_object;
36
-
37
- add_action( 'admin_menu', array( $this, 'create_admin_menu' ), 10 );
38
- add_action('admin_head', array( $this, 'mi_add_styles_for_menu' ) );
39
-
40
- if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
41
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
42
- }
43
-
44
- if ( is_plugin_active_for_network( GAWP_PATH ) ) {
45
- add_action( 'network_admin_menu', array( $this, 'create_admin_menu' ), 5 );
46
- }
47
-
48
- $this->dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
49
- $this->parent_slug = ( ( $this->dashboards_disabled ) ? 'yst_ga_settings' : 'yst_ga_dashboard' );
50
- }
51
-
52
- public function mi_add_styles_for_menu() {
53
- ?>
54
- <style type="text/css">
55
- @font-face {
56
- font-family: 'MonsterInsights';
57
- src: url('data:application/octet-stream;base64,d09GRgABAAAAAA38AA8AAAAAFwQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABWAAAADMAAABCsP6z7U9TLzIAAAGMAAAAQgAAAFZWgGHYY21hcAAAAdAAAABOAAABcAGIBM1jdnQgAAACIAAAABMAAAAgBtX/BGZwZ20AAAI0AAAFkAAAC3CKkZBZZ2FzcAAAB8QAAAAIAAAACAAAABBnbHlmAAAHzAAAA4UAAAQ4Qjh5qmhlYWQAAAtUAAAAMAAAADYJc4g3aGhlYQAAC4QAAAAbAAAAJAc8A1VobXR4AAALoAAAAAgAAAAIB9AAAGxvY2EAAAuoAAAABgAAAAYCHAAAbWF4cAAAC7AAAAAgAAAAIAGlDKNuYW1lAAAL0AAAAXcAAALNzJ0cHnBvc3QAAA1IAAAANgAAAEjuwMydcHJlcAAADYAAAAB6AAAAhuVBK7x4nGNgZGBg4GKQY9BhYHRx8wlh4GBgYYAAkAxjTmZ6IlAMygPKsYBpDiBmg4gCAIojA08AeJxjYGR+wTiBgZWBgamKaQ8DA0MPhGZ8wGDIyAQUZWBlZsAKAtJcUxgcGBIZEpmD/mcxRDEHMUwDCjOC5ADzdgsHAAB4nGNgYGBlYGBgBmIdIGZhYGAMYWBkAAE/oCgjWJyZgQsszsKgBFbDAhZP/P8fTjKCdIJEGdkYaA8Y6WAHJYAHTMpAeeCwgmJGAOC1B1YAAHicY2BAAxIQyBz0PwuEARJsA90AeJytVml300YUHXlJnIQsJQstamHExGmwRiZswYAJQbJjIF2crZWgixQ76b7xid/gX/Nk2nPoN35a7xsvJJC053Cak6N3583VzNtlElqS2AvrkZSbL8XU1iaN7DwJ6YZNy1F8KDt7IWWKyd8FURCtltq3HYdERCJQta6wRBD7HlmaZHzoUUbLtqRXTcotPekuW+NBvVXffho6yrE7oaRmM3RoPbIlVRhVokimPVLSpmWo+itJK7y/wsxXzVDCiE4iabwZxtBI3htntMpoNbbjKIpsstwoUiSa4UEUeZTVEufkigkMygfNkPLKpxHlw/yIrNijnFawS7bT/L4vead3OT+xX29RtuRAH8iO7ODsdCVfhFtbYdy0k+0oVBF213dCbNnsVP9mj/KaRgO3KzK90IxgqXyFECs/ocz+IVktnE/5kkejWrKRE0HrZU7sSz6B1uOIKXHNGFnQ3dEJEdT9kjMM9pg+Hvzx3imWCxMCeBzLekclnAgTKWFzNEnaMHJgJWWLKqn1rpg45XVaxFvCfu3a0ZfOaONQd2I8Ww8dWzlRyfFoUqeZTJ3aSc2jKQ2ilHQmeMyvAyg/oklebWM1iZVH0zhmxoREIgIt3EtTQSw7saQpBM2jGb25G6a5di1apMkD9dyj9/TmVri501PaDvSzRn9Wp2I62AvT6WnkL/Fp2uUiRen66Rl+TOJB1gIykS02w5SDB2/9DtLL15YchdcG2O7t8yuofdZE8KQB+xvQHk/VKQlMhZhViFZAYq1rWZbJ1awWqcjUd0OaVr6s0wSKchwXx76Mcf1fMzOWmBK+34nTsyMuPXPtSwjTHHybdT2a16nFcgFxZnlOp1mW7+s0x/IDneZZntfpCEtbp6MsP9RpgeVHOh1jeUELmnTfwZCLMOQCDpAwhKUDQ1hegiEsFQxhuQhDWBZhCMslGMLyYxjCchmGsLysZdXUU0nj2plYBmxCYGKOHrnMReVqKrlUQrtoVGpDnhJulVQUz6p/ZaBePPKGObAWSJfIml8xzpWPRuX41hUtbxo7V8Cx6m8fjvY58VLWi4U/Bf/V1lQlvWLNw5Or8BuGnmwnqjapeHRNl89VPbr+X1RUWAv0G0iFWCjKsmxwZyKEjzqdhmqglUPMbMw8tOt1y5qfw/03MUIWUP34NxQaC9yDTllJWe3grNXX27LcO4NyOBMsSTE38/pW+CIjs9J+kVnKno98HnAFjEpl2GoDrRW82ScxD5neJM8EcVtRNkja2M4EiQ0c84B5850EJmHqqg3kTuGGDfgFYW7BeSdconqjLIfuRezzKKT8W6fiRPaoaIzAs9kbYa/vQspvcQwkNPmlfgxUFaGpGDUV0DRSbqgGX8bZum1Cxg70Iyp2w7Ks4sPHFveVkm0ZhHykiNWjo5/WXqJOqtx+ZhSX752+BcEgNTF/e990cZDKu1rJMkdtA1O3GpVT15pD41WH6uZR9b3j7BM5a5puuiceel/TqtvBxVwssPZtDtJSJhfU9WGFDaLLxaVQ6mU0Se+4BxgWGNDvUIqN/6v62HyeK1WF0XEk307Ut9HnYAz8D9h/R/UD0Pdj6HINLs/3mhOfbvThbJmuohfrp+g3MGutuVm6BtzQdAPiIUetjrjKDXynBnF6pLkc6SHgY90V4gHAJoDF4BPdtYzmUwCj+Yw5PsDnzGHQZA6DLeYw2GbOGsAOcxjsMofBHnMYfMGcdYAvmcMgZA6DiDkMnjAnAHjKHAZfMYfB18xh8A1z7gN8yxwGMXMYJMxhsK/p1jDMLV7QXaC2QVWgA1NPWNzD4lBTZcj+jheG/b1BzP7BIKb+qOn2kPoTLwz1Z4OY+otBTP1V050h9TdeGOrvBjH1D4OY+ky/GMtlBr+MfJcKB5RdbD7n74n3D9vFQLkAAQAB//8AD3icpY9NbBtFFMfnzczu2rs7u+td764df2zitXdd27EdJ95N6uK6CUmTuBVEtCVFENKGtEFRCB8qIIoQzYVKKKhCcOu5By4gNYceEAIJIaScC4gPIQ5IKQeERK8U1hFIvXOY/8z/zXu/9x6KI/T3K+SALKBVdBlto9fQ22gX3UL30H3o956998tPP37x+acfBW1LSqgfg5L4DmT99/1bN2880jFjTP4aJPYmaNIfv71FeG3rudnpGIeNp5dURgUsAQHx5BvArjyG+aeewEDmfv35sztj9YpXyGckdbb/ifj4cu8sUhMJdQ3xGqX8OsKGIOF1BIggIFsogRQ9oVxAugky0+VVxJCkMWkFafEYpoZGV5CBEBhoNSliQSDnOCCEkYXMIVfdfghrYGHrf3PP91o71zY27v/5w/ff3P3qy73bH7x//Z1ruzu7L7+0sb2xvfn85UsXL6yunF9+8tzZM6f6C/OmxZlV20zyKvCe7/KC50enHYRBSEIvUtuyB8Z6+D4O0SXYwsBYQh7MpBDV25YCDaiDH8V5wXbbrumGnh+EnsuNR+qr0B7QLbvkR0W2dxwiE9nAIwrO4y6uYyEI6+AWlAhp5yF6tyfCbkS2ieWA7wnRbAPv+QPQ4bC2oDtAS6EfNY5C0U97ogsty47SQj8YbPNvcjRaY9DRtsJv5Tiv2TzoLUlgehrH00vZRwmH5WrKjBlyrqtU0umK0s0xPWamqjLm6KzcO1KmXNFIuiALmA6XqTAyqY1rvK6IB9qBqCu8ykkweTXNeO3dF1bqisDSOBOrg67yeEdSyyLlldhebd6nzdPLh7rPUfPMWP10fdhZn2h0zeQJt5S73nFEY/FE32UJrd8083bVFEUyVabyYtbQQQMNk/KM1eode3GkeHTt1UvZ3FwpvijT8hQRRbNm580H+8yA5CnOqnjDQ0zx4wRUZURSkhLOjnZGr87BvOG4YuAacrWcGWswt1BwWWMsU67KhjsZLzjGTb3d6s1M6s2hVkljlDILMxOcLB1yTCm1uZlS9HwGFuIJI02npzG2rET89RQxi7KaeUaWi0USSx+DafzfqpE2eL4WRMuGtUpR5U82fSeXpzQNOSVIENmwpppH/Br4jj1SKhfrVq40ajx4bw/rOuTjDbci8OOt9kxn7WhnwjbxFWO0lLPqRd8r2MPlvy4SJt5d+lAROIz+AYb2qh0AAAB4nGNgZGBgAOLOctXl8fw2Xxm4mV8ARRgumyl5I+j/xcwvmD2BXA4GJpAoACJyCgN4nGNgZGBgDvqfBSRfMDCASUYGVMAEAFz2A5kAA+gAAAPoAAAAAAAAAhwAAAABAAAAAgD1AAkAAAAAAAIALAA8AHMAAAD6C3AAAAAAeJx1kMtOwkAUhv+RiwqJGk3cOisDMZZLIgsSEhIMbHRDDFtTSmlLSodMBxJew3fwYXwJn8WfdjAGYpvpfOebM2dOB8A1viGQP08cOQucMcr5BKfoWS7QP1sukl8sl1DFm+Uy/bvlCh4QWK7iBh+sIIrnjBb4tCxwJS4tn+BC3Fku0D9aLpJ7lku4Fa+Wy/Se5QomIrVcxb34GqjVVkdBaGRtUJftZqsjp1upqKLEjaW7NqHSqezLuUqMH8fK8dRyz2M/WMeu3of7eeLrNFKJbDnNvRr5ia9d48921dNN0DZmLudaLeXQZsiVVgvfM05ozKrbaPw9DwMorLCFRsSrCmEgUaOtc26jiRY6pCkzJDPzrAgJXMQ0LtbcEWYrKeM+x5xRQuszIyY78PhdHvkxKeD+mFX00ephPCHtzogyL9mXw+4Os0akJMt0Mzv77T3Fhqe1aQ137brUWVcSw4MakvexW1vQePROdiuGtosG33/+7wfjaYRPAHicY2BigAAuBuyAiZGJkZlBLjc/r7gktSgzrzgzPaOkWFdXt7gsXRcomq+rYaTJwAAA1sMLEgAAeJxj8N7BcCIoYiMjY1/kBsadHAwcDMkFGxlYnTYxMDJogRibuZgYOSAsPgYwi81pF9MBoDQnkM3utIvBAcJmZnDZqMLYERixwaEjYiNzistGNRBvF0cDAyOLQ0dySARISSQQbOZhYuTR2sH4v3UDS+9GJgYXAAx2I/QAAA==') format('woff'),
58
- url('data:application/octet-stream;base64,AAEAAAAPAIAAAwBwR1NVQrD+s+0AAAD8AAAAQk9TLzJWgGHYAAABQAAAAFZjbWFwAYgEzQAAAZgAAAFwY3Z0IAbV/wQAAArsAAAAIGZwZ22KkZBZAAALDAAAC3BnYXNwAAAAEAAACuQAAAAIZ2x5ZkI4eaoAAAMIAAAEOGhlYWQJc4g3AAAHQAAAADZoaGVhBzwDVQAAB3gAAAAkaG10eAfQAAAAAAecAAAACGxvY2ECHAAAAAAHpAAAAAZtYXhwAaUMowAAB6wAAAAgbmFtZcydHB4AAAfMAAACzXBvc3TuwMydAAAKnAAAAEhwcmVw5UErvAAAFnwAAACGAAEAAAAKAB4ALAABREZMVAAIAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAAAAQPoAZAABQAAAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABAAGEAYQNS/2oAWgNSAJYAAAABAAAAAAAAAAAABQAAAAMAAAAsAAAABAAAAVQAAQAAAAAATgADAAEAAAAsAAMACgAAAVQABAAiAAAABAAEAAEAAABh//8AAABh//8AAAABAAQAAAABAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAcAAAAAAAAAAEAAABhAAAAYQAAAAEACQAA/3MD6ANJAGAAZwBvAHcAgACNAKYA6QD0AUtAX+nh3dzBwLyqNjUWCxEPrwEOEdgBDBLuy6ackD07FQgNDMgBCw18ARAL8Op+AwYQbWRFQggFAhNcUQ8NBAcCCwEDAQpHegENdU8CBlpTAgEDRuXfvrgxLiomIh4bCw9FS7AKUFhAVQAPEREPYwAGEAQEBmUAAhMHCwJlAAEAAwABA20AEQAOEhEOYQASFQEMDRIMYAANAAsQDQteABAJCAIEExAEXgATAAABEwBgFAoCBwcDVgUBAwMNA0kbQFUADxEPbwAGEAQEBmUAAhMHEwIHbQABAAMAAQNtABEADhIRDmEAEhUBDA0SDGAADQALEA0LXgAQCQgCBBMQBF4AEwAAARMAYBQKAgcHA1YFAQMDDQNJWUAygoFoaPTz29rW1cbEtLOUkoiHgY2CjXJxaG9ob2tpZ2ZiYWBeWVhXVlVUTEtJSBUWBRUrFxUUBg8BBiYnIwYHJicGByY1Njc2NwM3Jjc2NxcWFzY3NjcWFxYXNjc2NxYXFhc2PwEWFxYHFwcWFxYXFgceARUUBwYPARcWDgEvAS4BJwcWFwYHFyM1IxUjNyYnNjcmIwUzNjcmJw8BNSYnBgcWFyUnBx4BFyY/AQYHFgcWFzYmAw4CHgI+Ai4CBzY3LgEjIg4BFRQXHgE3LgE1NDc+ARcWFwMWHwEnJgcGByY3PgEXJicmJwYHBgcmJwYXBxIfAQQlNycuAScGBwYmJyY1ND4BMhYXPgEXNyc2JwYHJicmJwYHBgcBLgEvAQYHFhcWN9cMCQYQFwYBEjILBw0SGQIJGVEcRAMFAgwrGBUIEwwdPg4qGRkqDj4dDRIIFRgrDAIFBEUMQCkoBAUkExQjAQwHAgQgKAQHITgQMxAGEg4K6BDoChIOBg8FCwE4exkNBhCLbl4uDgcNGQIbCC4BEg8GAoILDygKBAYOCLQsSCcEME1YSCcEME3LBQQVVDEuTS4gH2U0Lz4VFEEjJR2IOx8KE0pBSyMNERBLMBUeFysVCgoDOSgEDEocExIBEAEQAgMoQxYyQDxwISQ6Y3ZmHB1GJQlKDAQoOQMKChUsFx4V/ssNEwEUTAUWKiYgGg0OJwkDAQ8OIQsOFAsCHC07LXtGAUgTHyMKNiMTDCsoGzEvDSMiIiMNLzEbKCsMEyM4CSIfE5wSNTJAQzgSMBoyJRANBAQNFgINFQEfHAQaHxULGGtrGA4SHhsBSQkRExkEQkICAhYWEQl4GAMVJAwPG10MDCQkAwgZPAFCAjBNWEgnBDBNWEgnLwYGLDYuTS43LCokDwZHMCcfHR4EBBkBHQ42EQMMExY5MCknLAEnHxchJSgkLhYdJS0T/o60AhISAR4JLyMqBwYzMjVDO2M6OzQXFQJ1Ey0lHRYuJCcmIhcgKP1iAw0K1VGVDgcFAgAAAQAAAAEAAIl3JadfDzz1AAsD6AAAAADTNiJLAAAAANM2IksAAP9zA+gDSQAAAAgAAgAAAAAAAAABAAADUv9qAAAD6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAgPoAAAD6AAAAAAAAAIcAAAAAQAAAAIA9QAJAAAAAAACACwAPABzAAAA+gtwAAAAAAAAABIA3gABAAAAAAAAADUAAAABAAAAAAABAAgANQABAAAAAAACAAcAPQABAAAAAAADAAgARAABAAAAAAAEAAgATAABAAAAAAAFAAsAVAABAAAAAAAGAAgAXwABAAAAAAAKACsAZwABAAAAAAALABMAkgADAAEECQAAAGoApQADAAEECQABABABDwADAAEECQACAA4BHwADAAEECQADABABLQADAAEECQAEABABPQADAAEECQAFABYBTQADAAEECQAGABABYwADAAEECQAKAFYBcwADAAEECQALACYByUNvcHlyaWdodCAoQykgMjAxNiBieSBvcmlnaW5hbCBhdXRob3JzIEAgZm9udGVsbG8uY29tZm9udGVsbG9SZWd1bGFyZm9udGVsbG9mb250ZWxsb1ZlcnNpb24gMS4wZm9udGVsbG9HZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAAMgAwADEANgAgAGIAeQAgAG8AcgBpAGcAaQBuAGEAbAAgAGEAdQB0AGgAbwByAHMAIABAACAAZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AZgBvAG4AdABlAGwAbABvAFIAZQBnAHUAbABhAHIAZgBvAG4AdABlAGwAbABvAGYAbwBuAHQAZQBsAGwAbwBWAGUAcgBzAGkAbwBuACAAMQAuADAAZgBvAG4AdABlAGwAbABvAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAACAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAgEDAB5tb25zdGVyaW5zaWdodHMtLS1zdmctbW9uby0oMikAAAABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAYABgAGAAYA1L/agNS/2qwACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBksQViQiCwBiNCsQEKQ0VjsQEKQ7ABYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZISCwQFNYsAErGyGwQFkjsABQWGVZLbAFLLAHQyuyAAIAQ2BCLbAGLLAHI0IjILAAI0JhsAJiZrABY7ABYLAFKi2wBywgIEUgsAtDY7gEAGIgsABQWLBAYFlmsAFjYESwAWAtsAgssgcLAENFQiohsgABAENgQi2wCSywAEMjRLIAAQBDYEItsAosICBFILABKyOwAEOwBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAssICBFILABKyOwAEOwBCVgIEWKI2EgZLAkUFiwABuwQFkjsABQWGVZsAMlI2FERLABYC2wDCwgsAAjQrILCgNFWCEbIyFZKiEtsA0ssQICRbBkYUQtsA4ssAFgICCwDENKsABQWCCwDCNCWbANQ0qwAFJYILANI0JZLbAPLCCwEGJmsAFjILgEAGOKI2GwDkNgIIpgILAOI0IjLbAQLEtUWLEEZERZJLANZSN4LbARLEtRWEtTWLEEZERZGyFZJLATZSN4LbASLLEAD0NVWLEPD0OwAWFCsA8rWbAAQ7ACJUKxDAIlQrENAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAOKiEjsAFhIIojYbAOKiEbsQEAQ2CwAiVCsAIlYbAOKiFZsAxDR7ANQ0dgsAJiILAAUFiwQGBZZrABYyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsQAAEyNEsAFDsAA+sgEBAUNgQi2wEywAsQACRVRYsA8jQiBFsAsjQrAKI7ABYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wFCyxABMrLbAVLLEBEystsBYssQITKy2wFyyxAxMrLbAYLLEEEystsBkssQUTKy2wGiyxBhMrLbAbLLEHEystsBwssQgTKy2wHSyxCRMrLbAeLACwDSuxAAJFVFiwDyNCIEWwCyNCsAojsAFgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAfLLEAHistsCAssQEeKy2wISyxAh4rLbAiLLEDHistsCMssQQeKy2wJCyxBR4rLbAlLLEGHistsCYssQceKy2wJyyxCB4rLbAoLLEJHistsCksIDywAWAtsCosIGCwEGAgQyOwAWBDsAIlYbABYLApKiEtsCsssCorsCoqLbAsLCAgRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOCMgilVYIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgbIVktsC0sALEAAkVUWLABFrAsKrABFTAbIlktsC4sALANK7EAAkVUWLABFrAsKrABFTAbIlktsC8sIDWwAWAtsDAsALABRWO4BABiILAAUFiwQGBZZrABY7ABK7ALQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixLwEVKi2wMSwgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhOC2wMiwuFzwtsDMsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYbABQ2M4LbA0LLECABYlIC4gR7AAI0KwAiVJiopHI0cjYSBYYhshWbABI0KyMwEBFRQqLbA1LLAAFrAEJbAEJUcjRyNhsAlDK2WKLiMgIDyKOC2wNiywABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyCwCEMgiiNHI0cjYSNGYLAEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsAJiILAAUFiwQGBZZrABY2AjILABKyOwBENgsAErsAUlYbAFJbACYiCwAFBYsEBgWWawAWOwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbA3LLAAFiAgILAFJiAuRyNHI2EjPDgtsDgssAAWILAII0IgICBGI0ewASsjYTgtsDkssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbkIAAgAY2MjIFhiGyFZY7gEAGIgsABQWLBAYFlmsAFjYCMuIyAgPIo4IyFZLbA6LLAAFiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wOywjIC5GsAIlRlJYIDxZLrErARQrLbA8LCMgLkawAiVGUFggPFkusSsBFCstsD0sIyAuRrACJUZSWCA8WSMgLkawAiVGUFggPFkusSsBFCstsD4ssDUrIyAuRrACJUZSWCA8WS6xKwEUKy2wPyywNiuKICA8sAQjQoo4IyAuRrACJUZSWCA8WS6xKwEUK7AEQy6wKystsEAssAAWsAQlsAQmIC5HI0cjYbAJQysjIDwgLiM4sSsBFCstsEEssQgEJUKwABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyBHsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhsAIlRmE4IyA8IzgbISAgRiNHsAErI2E4IVmxKwEUKy2wQiywNSsusSsBFCstsEMssDYrISMgIDywBCNCIzixKwEUK7AEQy6wKystsEQssAAVIEewACNCsgABARUUEy6wMSotsEUssAAVIEewACNCsgABARUUEy6wMSotsEYssQABFBOwMiotsEcssDQqLbBILLAAFkUjIC4gRoojYTixKwEUKy2wSSywCCNCsEgrLbBKLLIAAEErLbBLLLIAAUErLbBMLLIBAEErLbBNLLIBAUErLbBOLLIAAEIrLbBPLLIAAUIrLbBQLLIBAEIrLbBRLLIBAUIrLbBSLLIAAD4rLbBTLLIAAT4rLbBULLIBAD4rLbBVLLIBAT4rLbBWLLIAAEArLbBXLLIAAUArLbBYLLIBAEArLbBZLLIBAUArLbBaLLIAAEMrLbBbLLIAAUMrLbBcLLIBAEMrLbBdLLIBAUMrLbBeLLIAAD8rLbBfLLIAAT8rLbBgLLIBAD8rLbBhLLIBAT8rLbBiLLA3Ky6xKwEUKy2wYyywNyuwOystsGQssDcrsDwrLbBlLLAAFrA3K7A9Ky2wZiywOCsusSsBFCstsGcssDgrsDsrLbBoLLA4K7A8Ky2waSywOCuwPSstsGossDkrLrErARQrLbBrLLA5K7A7Ky2wbCywOSuwPCstsG0ssDkrsD0rLbBuLLA6Ky6xKwEUKy2wbyywOiuwOystsHAssDorsDwrLbBxLLA6K7A9Ky2wciyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sAEVMC0AS7gAyFJYsQEBjlmwAbkIAAgAY3CxAAVCsgABACqxAAVCswoCAQgqsQAFQrMOAAEIKrEABkK6AsAAAQAJKrEAB0K6AEAAAQAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVmzDAIBDCq4Af+FsASNsQIARAAA') format('truetype');
59
- font-weight: normal;
60
- font-style: normal;
61
- }
62
-
63
- #toplevel_page_yst_ga_dashboard .wp-menu-image:before,
64
- .yst_ga_dashboard-menu-icon:before {
65
-
66
- font-family: "MonsterInsights" !important;
67
- content: '\61';
68
- font-style: normal !important;
69
- font-weight: normal !important;
70
- font-variant: normal !important;
71
- text-transform: none !important;
72
- speak: none;
73
- line-height: 1;
74
- -webkit-font-smoothing: antialiased;
75
- -moz-osx-font-smoothing: grayscale;
76
- color: #fff;
77
- }
78
- #toplevel_page_yst_ga_dashboard .wp-menu-image:before {
79
- font-size: 1.5em;
80
- padding-top: 4px;
81
- padding-bottom: 2px;
82
- font-size: 22px;
83
- }
84
- </style>
85
- <?php
86
- }
87
-
88
- /**
89
- * Create the admin menu
90
- */
91
- public function create_admin_menu() {
92
- $menu_name = is_network_admin() ? 'extensions' : 'dashboard';
93
-
94
- if ( $this->dashboards_disabled ) {
95
- $menu_name = 'settings';
96
- }
97
-
98
- // Add main page
99
- add_menu_page(
100
- __( 'Google Analytics by MonsterInsights:', 'google-analytics-for-wordpress' ) . ' ' . __( 'General settings', 'google-analytics-for-wordpress' ), __( 'Insights', 'google-analytics-for-wordpress' ), 'manage_options', 'yst_ga_' . $menu_name,
101
- array(
102
- $this->target_object,
103
- 'load_page',
104
- ),
105
- '',
106
- '100.00013467543'
107
- );
108
-
109
-
110
- $this->add_submenu_pages();
111
- }
112
-
113
- /**
114
- * Prepares an array that can be used to add a submenu page to the Google Analytics for Wordpress menu
115
- *
116
- * @param string $submenu_name
117
- * @param string $submenu_slug
118
- * @param string $font_color
119
- *
120
- * @return array
121
- */
122
- private function prepare_submenu_page( $submenu_name, $submenu_slug, $font_color = '' ) {
123
- return array(
124
- 'parent_slug' => $this->parent_slug,
125
- 'page_title' => __( 'Google Analytics by MonsterInsights:', 'google-analytics-for-wordpress' ) . ' ' . $submenu_name,
126
- 'menu_title' => $this->parse_menu_title( $submenu_name, $font_color ),
127
- 'capability' => 'manage_options',
128
- 'menu_slug' => 'yst_ga_' . $submenu_slug,
129
- 'submenu_function' => array( $this->target_object, 'load_page' ),
130
- );
131
- }
132
-
133
- /**
134
- * Parsing the menutitle
135
- *
136
- * @param string $menu_title
137
- * @param string $font_color
138
- *
139
- * @return string
140
- */
141
- private function parse_menu_title( $menu_title, $font_color ) {
142
- if ( ! empty( $font_color ) ) {
143
- $menu_title = '<span style="color:' . $font_color . '">' . $menu_title . '</span>';
144
- }
145
-
146
- return $menu_title;
147
- }
148
-
149
- /**
150
- * Adds a submenu page to the Google Analytics for WordPress menu
151
- *
152
- * @param array $submenu_page
153
- */
154
- private function add_submenu_page( $submenu_page ) {
155
- $page = add_submenu_page( $submenu_page['parent_slug'], $submenu_page['page_title'], $submenu_page['menu_title'], $submenu_page['capability'], $submenu_page['menu_slug'], $submenu_page['submenu_function'] );
156
- $is_dashboard = ( 'yst_ga_dashboard' === $submenu_page['menu_slug'] );
157
- $this->add_assets( $page, $is_dashboard );
158
- }
159
-
160
- /**
161
- * Adding stylesheets and based on $is_not_dashboard maybe some more styles and scripts.
162
- *
163
- * @param string $page
164
- * @param boolean $is_dashboard
165
- */
166
- private function add_assets( $page, $is_dashboard ) {
167
- add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_styles' ) );
168
- add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_settings_styles' ) );
169
- add_action( 'admin_print_scripts-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_scripts' ) );
170
- if ( ! $is_dashboard && filter_input( INPUT_GET, 'page' ) === 'yst_ga_dashboard' ) {
171
- Yoast_GA_Admin_Assets::enqueue_dashboard_assets();
172
- }
173
- }
174
-
175
- /**
176
- * Prepares and adds submenu pages to the Google Analytics for Wordpress menu:
177
- * - Dashboard
178
- * - Settings
179
- * - Extensions
180
- *
181
- * @return void
182
- */
183
- private function add_submenu_pages() {
184
- foreach ( $this->get_submenu_types() as $submenu ) {
185
- if ( isset( $submenu['color'] ) ) {
186
- $submenu_page = $this->prepare_submenu_page( $submenu['label'], $submenu['slug'], $submenu['color'] );
187
- }
188
- else {
189
- $submenu_page = $this->prepare_submenu_page( $submenu['label'], $submenu['slug'] );
190
- }
191
- $this->add_submenu_page( $submenu_page );
192
- }
193
- }
194
-
195
- /**
196
- * Determine which submenu types should be added as a submenu page.
197
- *
198
- * Dashboard can be disables by user
199
- *
200
- * Dashboard and settings are disables in network admin
201
- *
202
- * @return array
203
- */
204
- private function get_submenu_types() {
205
- /**
206
- * Array structure:
207
- *
208
- * array(
209
- * $submenu_name => array(
210
- * 'color' => $font_color,
211
- * 'label' => __( 'text-label', 'google-analytics-for-wordpress' ),
212
- * 'slug' => $menu_slug,
213
- * ),
214
- * ..,
215
- * )
216
- *
217
- * $font_color can be left empty.
218
- *
219
- */
220
- $submenu_types = array();
221
-
222
- if ( ! is_network_admin() ) {
223
-
224
- if ( ! $this->dashboards_disabled ) {
225
- $submenu_types['dashboard'] = array(
226
- 'label' => __( 'Dashboard', 'google-analytics-for-wordpress' ),
227
- 'slug' => 'dashboard',
228
- );
229
- }
230
-
231
- $submenu_types['settings'] = array(
232
- 'label' => __( 'Settings', 'google-analytics-for-wordpress' ),
233
- 'slug' => 'settings',
234
- );
235
- }
236
-
237
- $submenu_types['extensions'] = array(
238
- 'color' => '#f18500',
239
- 'label' => __( 'Extensions', 'google-analytics-for-wordpress' ),
240
- 'slug' => 'extensions',
241
- );
242
-
243
- return $submenu_types;
244
- }
245
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-admin.php DELETED
@@ -1,620 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * This class is for the backend, extendable for all child classes
8
- */
9
- class Yoast_GA_Admin extends Yoast_GA_Options {
10
-
11
- /**
12
- * Constructor
13
- */
14
- public function __construct() {
15
- parent::__construct();
16
-
17
- add_action( 'plugins_loaded', array( $this, 'init_ga' ) );
18
-
19
- // Only run admin_init when there is a cron jon executed.
20
- $current_page = filter_input( INPUT_GET, 'page' );
21
-
22
- // Only when current page is not 'wpseo'.
23
- if ( strpos( $current_page, 'wpseo' ) !== 0 ) {
24
- if ( ( $this->is_running_cron() || $this->is_running_ajax() ) || strpos( $current_page, 'yst_ga' ) === 0 ) {
25
- add_action( 'admin_init', array( $this, 'init_settings' ) );
26
- }
27
- }
28
-
29
- add_action( 'admin_init', array( $this, 'system_info' ) );
30
-
31
- }
32
-
33
- /**
34
- * Init function when the plugin is loaded
35
- */
36
- public function init_ga() {
37
-
38
- new Yoast_GA_Admin_Menu( $this );
39
-
40
- add_filter( 'plugin_action_links_' . plugin_basename( GAWP_FILE ), array( $this, 'add_action_links' ) );
41
-
42
- }
43
-
44
- /**
45
- * Init function for the settings of GA
46
- */
47
- public function init_settings() {
48
- $this->options = $this->get_options();
49
-
50
- try {
51
- // Loading Google Api Libs with minimal version 2.0.
52
- new MI_Api_Libs( '2.0' );
53
- }
54
- catch( Exception $exception ) {
55
- if ( $exception->getMessage() === 'required_version' ) {
56
- add_action( 'admin_notices', array( $this, 'set_api_libs_error' ) );
57
- }
58
- }
59
-
60
- $dashboards = Yoast_GA_Dashboards::get_instance();
61
-
62
- // Listener for reconnecting with google analytics
63
- $this->google_analytics_listener();
64
-
65
- if ( is_null( $this->get_tracking_code() ) && $this->show_admin_warning() ) {
66
- add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', 'config_warning' ) );
67
- }
68
-
69
- // Check if something has went wrong with GA-api calls
70
- $has_tracking_code = ( ! is_null( $this->get_tracking_code() ) && empty( $this->options['manual_ua_code_field'] ) );
71
- if ( $has_tracking_code && $this->show_admin_dashboard_warning() ) {
72
- Yoast_Google_Analytics::get_instance()->check_for_ga_issues();
73
- }
74
-
75
-
76
- if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
77
- $this->handle_ga_post_request( $dashboards );
78
- }
79
-
80
- /**
81
- * Show the notifications if we have one
82
- */
83
- $this->show_notification( 'ga_notifications' );
84
-
85
- // Load the Google Analytics Dashboards functionality
86
- $dashboards->init_dashboards( $this->get_current_profile() );
87
- }
88
-
89
- /**
90
- * There is an error with the API libs. So show a notice.
91
- */
92
- public function set_api_libs_error() {
93
- echo '<div class="error notice"><p>' . __( 'MonsterInsights plugins share some code between them to make your site faster. As a result of that, we need all MonsterInsights plugins to be up to date. We\'ve detected this isn\'t the case, so please update the MonsterInsights plugins that aren\'t up to date yet.', 'google-analytics-for-wordpress' ) . '</p></div>';
94
- }
95
-
96
- /**
97
- * This function saves the settings in the option field and returns a wp success message on success
98
- *
99
- * @param array $data
100
- */
101
- public function save_settings( $data ) {
102
-
103
- unset( $data['google_auth_code'] );
104
-
105
- foreach ( $data as $key => $value ) {
106
- if ( $key != 'return_tab' ) {
107
- if ( is_string( $value ) ) {
108
- if ( $key === 'custom_code' && ! current_user_can( 'unfiltered_html' ) ) {
109
- continue;
110
- }
111
- else {
112
- $value = strip_tags( $value );
113
- }
114
- }
115
-
116
- $this->options[ $key ] = $value;
117
- }
118
- }
119
-
120
- // Check checkboxes, on a uncheck they won't be posted to this function
121
- $defaults = $this->default_ga_values();
122
- foreach ( $defaults[ $this->option_prefix ] as $option_name => $value ) {
123
- $this->handle_default_setting( $data, $option_name, $value );
124
- }
125
-
126
- if ( ! empty( $this->options['analytics_profile'] ) ) {
127
- $this->options['analytics_profile_code'] = $this->get_ua_code_from_profile( $this->options['analytics_profile'] );
128
- }
129
-
130
- $this->do_validation( $data['return_tab'] );
131
-
132
- if ( $this->update_option( $this->options ) ) {
133
- // Success, add a new notification
134
- $this->add_notification( 'ga_notifications', array(
135
- 'type' => 'success',
136
- 'description' => __( 'Settings saved.', 'google-analytics-for-wordpress' ),
137
- ) );
138
- }
139
- else {
140
- // Fail, add a new notification
141
- $this->add_notification( 'ga_notifications', array(
142
- 'type' => 'error',
143
- 'description' => __( 'There were no changes to save, please try again.', 'google-analytics-for-wordpress' ),
144
- ) );
145
- }
146
-
147
- // redirect
148
- wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $data['return_tab'], 301 );
149
- exit;
150
- }
151
-
152
- /**
153
- * Redirect to settings with a validation error if there are validation errors
154
- *
155
- * @param string $return_tab The tab to return to when there is a validation error.
156
- */
157
- protected function do_validation( $return_tab ) {
158
- $validation = $this->validate_settings();
159
- if ( is_wp_error( $validation ) ) {
160
- $this->add_notification( 'ga_notifications', array(
161
- 'type' => 'error',
162
- 'description' => $validation->get_error_message(),
163
- ) );
164
-
165
- wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $return_tab, 301 );
166
- exit;
167
- }
168
- }
169
-
170
- /**
171
- * Validates the settings in the `options` attribute, returns an WP_Error object on error
172
- *
173
- * @return true|WP_Error true or an error object.
174
- */
175
- protected function validate_settings() {
176
-
177
- if ( ! empty( $this->options['manual_ua_code_field'] ) ) {
178
- $this->options['manual_ua_code_field'] = trim( $this->options['manual_ua_code_field'] );
179
- // en dash to minus, prevents issue with code copied from web with "fancy" dash
180
- $this->options['manual_ua_code_field'] = str_replace( '–', '-', $this->options['manual_ua_code_field'] );
181
-
182
- // Regex to tests if a valid UA code has been set. Valid codes follow: "UA-[4 digits]-[at least 1 digit]".
183
- if ( ! preg_match( '|^UA-\d{4,}-\d+$|', $this->options['manual_ua_code_field'] ) ) {
184
-
185
- return new WP_Error(
186
- 'ua-code-format',
187
- __( 'The UA code needs to follow UA-XXXXXXXX-X format.', 'google-analytics-for-wordpress' )
188
- );
189
- }
190
- }
191
-
192
- /**
193
- * Filters the validation for the admin options
194
- *
195
- * @param true|WP_Error true if the validation is successful, WP_Error on error.
196
- * @param array $this->options The options that are being saved.
197
- */
198
- return apply_filters( 'yst_ga_admin_validate_settings', true, $this->options );
199
- }
200
-
201
- /**
202
- * Run a this deactivation hook on deactivation of GA. When this happens we'll
203
- * remove the options for the profiles and the refresh token.
204
- */
205
- public static function ga_deactivation_hook() {
206
- // Remove the refresh token and other API settings
207
- self::analytics_api_clean_up();
208
- }
209
-
210
- /**
211
- * Handle a default setting in GA
212
- *
213
- * @param array $data
214
- * @param string $option_name
215
- * @param mixed $value
216
- */
217
- private function handle_default_setting( $data, $option_name, $value ) {
218
- if ( ! isset( $data[ $option_name ] ) ) {
219
- // If no data was passed in, set it to the default.
220
- if ( $value === 1 ) {
221
- // Disable the checkbox for now, use value 0
222
- $this->options[ $option_name ] = 0;
223
- }
224
- else {
225
- $this->options[ $option_name ] = $value;
226
- }
227
- }
228
- }
229
-
230
- /**
231
- * Handle the post requests in the admin form of the GA plugin
232
- *
233
- * @param Yoast_GA_Dashboards $dashboards
234
- */
235
- private function handle_ga_post_request( $dashboards ) {
236
- if ( ! function_exists( 'wp_verify_nonce' ) ) {
237
- require_once( ABSPATH . 'wp-includes/pluggable.php' );
238
- }
239
-
240
- if ( isset( $_POST['ga-form-settings'] ) && wp_verify_nonce( $_POST['yoast_ga_nonce'], 'save_settings' ) ) {
241
- if ( ! isset ( $_POST['ignore_users'] ) ) {
242
- $_POST['ignore_users'] = array();
243
- }
244
-
245
- $dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
246
-
247
- if ( ( $dashboards_disabled == false && isset( $_POST['dashboards_disabled'] ) ) || $this->ga_profile_changed( $_POST ) ) {
248
- $dashboards->reset_dashboards_data();
249
- }
250
-
251
- // Post submitted and verified with our nonce
252
- $this->save_settings( $_POST );
253
- }
254
- }
255
-
256
- /**
257
- * Is there selected an other property in the settings post? Returns true or false.
258
- *
259
- * @param array $post
260
- *
261
- * @return bool
262
- */
263
- private function ga_profile_changed( $post ) {
264
- if ( isset( $post['analytics_profile'] ) && isset( $this->options['analytics_profile'] ) ) {
265
- if ( $post['analytics_profile'] != $this->options['analytics_profile'] ) {
266
- return true;
267
- }
268
- }
269
-
270
- return false;
271
- }
272
-
273
- /**
274
- * Are we allowed to show a warning message? returns true if it's allowed
275
- *
276
- * @return bool
277
- */
278
- private function show_admin_warning() {
279
- return ( current_user_can( 'manage_options' ) && ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) );
280
- }
281
-
282
- /**
283
- * Are we allowed to show a warning message? returns true if it's allowed ( this is meant to be only for dashboard )
284
- *
285
- * @return bool
286
- */
287
- private function show_admin_dashboard_warning() {
288
- return ( current_user_can( 'manage_options' ) && isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' );
289
- }
290
-
291
- /**
292
- * Transform the Profile ID into an helpful UA code
293
- *
294
- * @param integer $profile_id
295
- *
296
- * @return null
297
- */
298
- private function get_ua_code_from_profile( $profile_id ) {
299
- $profiles = $this->get_profiles();
300
- $ua_code = null;
301
-
302
- foreach ( $profiles as $account ) {
303
- foreach ( $account['items'] as $profile ) {
304
- foreach ( $profile['items'] as $subprofile ) {
305
- if ( isset( $subprofile['id'] ) && $subprofile['id'] === $profile_id ) {
306
- return $subprofile['ua_code'];
307
- }
308
- }
309
- }
310
- }
311
-
312
- return $ua_code;
313
- }
314
-
315
- /**
316
- * Add a link to the settings page to the plugins list
317
- *
318
- * @param array $links array of links for the plugins, adapted when the current plugin is found.
319
- *
320
- * @return array $links
321
- */
322
- public function add_action_links( $links ) {
323
- // add link to knowledgebase
324
- // @todo UTM link fix
325
- $faq_link = '<a title="MonsterInsights Knowledge Base" href="http://www.monsterinsights.com/docs/">' . __( 'FAQ', 'google-analytics-for-wordpress' ) . '</a>';
326
- array_unshift( $links, $faq_link );
327
-
328
- $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=yst_ga_settings' ) ) . '">' . __( 'Settings', 'google-analytics-for-wordpress' ) . '</a>';
329
- array_unshift( $links, $settings_link );
330
-
331
- return $links;
332
- }
333
-
334
- /**
335
- * Adds some promo text for the premium plugin on the custom dimensions tab.
336
- */
337
- public function premium_promo() {
338
- echo '<div class="ga-promote">';
339
- echo '<p>';
340
- printf( __( 'If you want to track custom dimensions like page views per author or post type, you should upgrade to the %1$spremium version of Google Analytics by MonsterInsights%2$s.', 'google-analytics-for-wordpress' ), '<a href="https://www.monsterinsights.com/pricing/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin&utm_content=custom_dimensions_tab">', '</a>' );
341
- echo ' ';
342
- _e( 'This will also give you access to the support team at MonsterInsights, who will provide support on the plugin 24/7.', 'google-analytics-for-wordpress' );
343
- echo '</p>';
344
- echo '</div>';
345
- }
346
-
347
- /**
348
- * Load the page of a menu item in the GA plugin
349
- */
350
- public function load_page() {
351
-
352
- if ( ! has_action( 'yst_ga_custom_dimensions_tab-content' ) ) {
353
- add_action( 'yst_ga_custom_dimensions_tab-content', array( $this, 'premium_promo' ) );
354
- }
355
-
356
- if ( ! has_action( 'yst_ga_custom_dimension_add-dashboards-tab' ) ) {
357
- add_action( 'yst_ga_custom_dimension_add-dashboards-tab', array( $this, 'premium_promo' ) );
358
- }
359
-
360
- switch ( filter_input( INPUT_GET, 'page' ) ) {
361
- case 'yst_ga_settings':
362
- require_once( $this->plugin_path . 'admin/pages/settings.php' );
363
- break;
364
- case 'yst_ga_extensions':
365
- require_once( $this->plugin_path . 'admin/pages/extensions.php' );
366
- break;
367
- case 'yst_ga_dashboard':
368
- default:
369
- require_once( $this->plugin_path . 'admin/pages/dashboard.php' );
370
- break;
371
- }
372
- }
373
-
374
-
375
- /**
376
- * Get the Google Analytics profiles which are in this google account
377
- *
378
- * @return array
379
- */
380
- public function get_profiles() {
381
- $return = Yoast_Google_Analytics::get_instance()->get_profiles();
382
-
383
- return $return;
384
- }
385
-
386
- /**
387
- * Checks if there is a callback to get token from Google Analytics API
388
- */
389
- private function google_analytics_listener() {
390
- $google_auth_code = filter_input( INPUT_POST, 'google_auth_code' );
391
- if ( $google_auth_code && current_user_can( 'manage_options' ) && wp_verify_nonce( filter_input( INPUT_POST, 'yoast_ga_nonce' ), 'save_settings' ) ) {
392
- self::analytics_api_clean_up();
393
-
394
- Yoast_Google_Analytics::get_instance()->authenticate( trim( $google_auth_code ) );
395
- }
396
- }
397
-
398
- /**
399
- * Clean up the Analytics API settings
400
- */
401
- public static function analytics_api_clean_up() {
402
- delete_option( 'yoast-ga-refresh_token' );
403
- delete_option( 'yst_ga_api_call_fail' );
404
- delete_option( 'yst_ga_last_wp_run' );
405
- delete_option( 'yst_ga_api' );
406
- }
407
-
408
- /**
409
- * Get the current GA profile
410
- *
411
- * @return null
412
- */
413
- private function get_current_profile() {
414
- if ( ! empty( $this->options['analytics_profile'] ) ) {
415
- return $this->options['analytics_profile'];
416
- }
417
-
418
- return null;
419
- }
420
-
421
- /**
422
- * Get the user roles of this WordPress blog
423
- *
424
- * @return array
425
- */
426
- public function get_userroles() {
427
- global $wp_roles;
428
-
429
- $all_roles = $wp_roles->roles;
430
- $roles = array();
431
-
432
- /**
433
- * Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
434
- *
435
- * @api array $all_roles
436
- */
437
- $editable_roles = apply_filters( 'editable_roles', $all_roles );
438
-
439
- foreach ( $editable_roles as $id => $name ) {
440
- $roles[] = array(
441
- 'id' => $id,
442
- 'name' => translate_user_role( $name['name'] ),
443
- );
444
- }
445
-
446
- return $roles;
447
- }
448
-
449
- /**
450
- * Get types of how we can track downloads
451
- *
452
- * @return array
453
- */
454
- public function track_download_types() {
455
- return array(
456
- 0 => array( 'id' => 'event', 'name' => __( 'Event', 'google-analytics-for-wordpress' ) ),
457
- 1 => array( 'id' => 'pageview', 'name' => __( 'Pageview', 'google-analytics-for-wordpress' ) ),
458
- );
459
- }
460
-
461
- /**
462
- * Get options for the track full url or links setting
463
- *
464
- * @return array
465
- */
466
- public function get_track_full_url() {
467
- return array(
468
- 0 => array( 'id' => 'domain', 'name' => __( 'Just the domain', 'google-analytics-for-wordpress' ) ),
469
- 1 => array( 'id' => 'full_links', 'name' => __( 'Full links', 'google-analytics-for-wordpress' ) ),
470
- );
471
- }
472
-
473
- /**
474
- * Render the admin page head for the GA Plugin
475
- */
476
- public function content_head() {
477
- require 'views/content_head.php';
478
- }
479
-
480
- /**
481
- * Output System Info file
482
- */
483
- public function system_info() {
484
- if ( ! empty( $_REQUEST['monsterinsights-action'] ) && $_REQUEST['monsterinsights-action'] === 'download_sysinfo' ) {
485
- if ( ! current_user_can( 'manage_options' ) ) {
486
- return;
487
- }
488
- nocache_headers();
489
- header( 'Content-Type: text/plain' );
490
- header( 'Content-Disposition: attachment; filename="monsterinsights-system-info.txt"' );
491
- echo wp_strip_all_tags( $_POST['monsterinsights-sysinfo'] );
492
- die();
493
- }
494
- }
495
-
496
- /**
497
- * Render the admin page footer with sidebar for the GA Plugin
498
- */
499
- public function content_footer() {
500
-
501
- do_action( 'yoast_ga_admin_footer' );
502
-
503
- if ( class_exists( 'MI_Product_GA_Premium' ) ) {
504
- $license_manager = new MI_Plugin_License_Manager( new MI_Product_GA_Premium() );
505
- if ( $license_manager->license_is_valid() ) {
506
- return;
507
- }
508
- }
509
-
510
- $banners = array();
511
- $banners[] = array(
512
- 'url' => 'https://optinmonster.com/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
513
- 'banner' => $this->plugin_url . 'assets/img/omupsell.png',
514
- 'title' => 'Convert Visitors into Subscribers',
515
- );
516
- $banners[] = array(
517
- 'url' => 'https://www.monsterinsights.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
518
- 'banner' => $this->plugin_url . 'assets/img/upgradetopro.png',
519
- 'title' => 'Get the premium version of Google Analytics by MonsterInsights!',
520
- );
521
- $banners[] = array(
522
- 'url' => 'http://www.wpbeginner.net/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
523
- 'banner' => $this->plugin_url . 'assets/img/wpbeginnerupsell.png',
524
- 'title' => 'The best collection of free beginner WordPress resources!',
525
- );
526
- $banners[] = array(
527
- 'url' => 'https://wpforms.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
528
- 'banner' => $this->plugin_url . 'assets/img/wpformsupsell.png',
529
- 'title' => 'Get the most beginner friendly WordPress contact form plugin in the market!',
530
- );
531
-
532
- shuffle( $banners );
533
-
534
- require 'views/content-footer.php';
535
-
536
- }
537
-
538
- /**
539
- * Returns a list of all available extensions
540
- *
541
- * @return array
542
- */
543
- public function get_extensions() {
544
- $extensions = array(
545
- 'ga_premium' => (object) array(
546
- 'url' => 'https://www.monsterinsights.com/pricing/',
547
- 'title' => __( 'Google Analytics by MonsterInsights Pro', 'google-analytics-for-wordpress' ),
548
- 'desc' => __( 'The premium version of Google Analytics by MonsterInsights with more features and support.', 'google-analytics-for-wordpress' ),
549
- 'status' => 'uninstalled',
550
- ),
551
- 'ecommerce' => (object) array(
552
- 'url' => 'https://www.monsterinsights.com/pricing/',
553
- 'title' => __( 'Google Analytics by MonsterInsights', 'google-analytics-for-wordpress' ) . '<br />' . __( 'eCommerce tracking', 'google-analytics-for-wordpress' ),
554
- 'desc' => __( 'Track your eCommerce data and transactions with this eCommerce extension for Google Analytics.', 'google-analytics-for-wordpress' ),
555
- 'status' => 'uninstalled',
556
- ),
557
- );
558
-
559
- $extensions = apply_filters( 'yst_ga_extension_status', $extensions );
560
-
561
- return $extensions;
562
- }
563
-
564
- /**
565
- * Add a notification to the notification transient
566
- *
567
- * @param string $transient_name
568
- * @param array $settings
569
- */
570
- private function add_notification( $transient_name, $settings ) {
571
- set_transient( $transient_name, $settings, MINUTE_IN_SECONDS );
572
- }
573
-
574
- /**
575
- * Show the notification that should be set, after showing the notification this function unset the transient
576
- *
577
- * @param string $transient_name The name of the transient which contains the notification
578
- */
579
- public function show_notification( $transient_name ) {
580
- $transient = get_transient( $transient_name );
581
-
582
- if ( isset( $transient['type'] ) && isset( $transient['description'] ) ) {
583
- if ( $transient['type'] == 'success' ) {
584
- add_settings_error(
585
- 'yoast_google_analytics',
586
- 'yoast_google_analytics',
587
- $transient['description'],
588
- 'updated'
589
- );
590
- }
591
- else {
592
- add_settings_error(
593
- 'yoast_google_analytics',
594
- 'yoast_google_analytics',
595
- $transient['description'],
596
- 'error'
597
- );
598
- }
599
-
600
- delete_transient( $transient_name );
601
- }
602
- }
603
-
604
- /**
605
- * Check if there the aggregate data cron is executed
606
- * @return bool
607
- */
608
- private function is_running_cron() {
609
- return doing_action( 'yst_ga_aggregate_data' ) && defined( 'DOING_CRON' ) && DOING_CRON;
610
- }
611
-
612
- /**
613
- * Check if there the aggregate data cron is executed
614
- * @return bool
615
- */
616
- private function is_running_ajax() {
617
- return defined( 'DOING_AJAX' ) && DOING_AJAX && strpos( filter_input( INPUT_GET, 'action' ), 'yoast_dashboard' ) === 0;
618
- }
619
-
620
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-google-analytics.php DELETED
@@ -1,365 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Google Analytics class.
8
- */
9
- class Yoast_Google_Analytics {
10
-
11
- /**
12
- * @var string
13
- */
14
- private $option_name = 'yst_ga_api';
15
-
16
- /**
17
- * @var array|mixed
18
- */
19
- private $options = array();
20
-
21
- /**
22
- * @var null|Yoast_Google_Analytics
23
- */
24
- private static $instance = null;
25
-
26
- /**
27
- * @var The api client object holder
28
- */
29
- private $client;
30
-
31
- /**
32
- * Singleton
33
- *
34
- */
35
- protected function __construct() {
36
-
37
- if ( is_null( self::$instance ) ) {
38
- self::$instance = $this;
39
- }
40
-
41
- $this->options = $this->get_options();
42
-
43
- // Setting the client
44
- $this->set_client();
45
- }
46
-
47
- /**
48
- * Getting the instance object
49
- *
50
- * This method will return the instance of itself, if instance not exists, becauses of it's called for the first
51
- * time, the instance will be created.
52
- *
53
- * @return null|Yoast_Google_Analytics
54
- */
55
- public static function get_instance() {
56
- if ( is_null( self::$instance ) ) {
57
- self::$instance = new self();
58
- }
59
-
60
- return self::$instance;
61
- }
62
-
63
-
64
- /**
65
- * Check if something went wrong with API calls to Google Analytics
66
- */
67
- public function check_for_ga_issues() {
68
-
69
- $last_run = get_option( 'yst_ga_last_wp_run' );
70
- $has_failed = get_option( 'yst_ga_api_call_fail', false );
71
-
72
- // Show error, something went wrong
73
- if ( $has_failed && ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 48 ) ) {
74
- $notice_type = 'warning_fetching_data';
75
-
76
- // Authentication has been successful, so there will be an access token
77
- if ( ! $this->client->getAccessToken() ) {
78
- $notice_type .= '_authenticate';
79
- }
80
-
81
- add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', $notice_type ) );
82
- }
83
-
84
- }
85
-
86
- /**
87
- * Wrapper for authenticate the client. If authentication code is send it will get and check an access token.
88
- *
89
- * @param mixed $authentication_code
90
- *
91
- * @return boolean
92
- */
93
- public function authenticate( $authentication_code = null ) {
94
- // When authentication again we should clean up some stuff
95
- $this->api_cleanup();
96
-
97
- return $this->client->authenticate_client( $authentication_code );
98
- }
99
-
100
- /**
101
- * Getting the analytics profiles
102
- *
103
- * Doing the request to the Google analytics API and if there is a response, parses this response and return its
104
- * array
105
- *
106
- * @return array
107
- */
108
- public function get_profiles() {
109
- $accounts = $this->format_profile_call(
110
- $this->do_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' )
111
- );
112
-
113
- if ( is_array( $accounts ) ) {
114
- $this->save_profile_response( $accounts );
115
-
116
- return $accounts;
117
- }
118
-
119
- return array();
120
- }
121
-
122
- /**
123
- * Doing request to Google Analytics
124
- *
125
- * This method will do a request to google and get the response code and body from content
126
- *
127
- * @param string $target_request_url
128
- *
129
- * @return array|null
130
- */
131
- public function do_request( $target_request_url ) {
132
-
133
- $response = $this->client->do_request( $target_request_url );
134
-
135
- if ( ! empty( $response ) ) {
136
- return array(
137
- 'response' => array( 'code' => $this->client->get_http_response_code() ),
138
- 'body' => json_decode( $response->getResponseBody(), true ),
139
- );
140
- }
141
-
142
- }
143
-
144
-
145
- /**
146
- * Check if client has a refresh token
147
- * @return bool
148
- */
149
- public function has_refresh_token() {
150
- return $this->client->is_authenticated();
151
- }
152
-
153
- /**
154
- * Getting the options bases on $this->option_name from the database
155
- *
156
- * @return mixed
157
- */
158
- public function get_options() {
159
- return get_option( $this->option_name );
160
- }
161
-
162
- /**
163
- * Checks whether we'll ever be able to reach Google.
164
- *
165
- * @return bool
166
- */
167
- public function check_google_access_from_wp() {
168
- $can_access_google = true;
169
- if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
170
- $can_access_google = false;
171
- if ( defined( 'WP_ACCESSIBLE_HOSTS' ) ) {
172
- // Better to use the internal WP logic from this point forward.
173
- $can_access_google = $this->test_connection_to_google();
174
- }
175
- }
176
-
177
- return $can_access_google;
178
- }
179
-
180
- /**
181
- * Check if we can access Google Apis from this server by making a dummy connection
182
- */
183
- public function check_google_access() {
184
- return $this->test_connection_to_google();
185
- }
186
-
187
- /**
188
- * Updating the options based on $this->option_name and the internal property $this->options
189
- */
190
- protected function update_options() {
191
- update_option( $this->option_name, $this->options );
192
- }
193
-
194
- /**
195
- * Setting the client
196
- *
197
- * The filter is a hook to override the configuration/
198
- */
199
- protected function set_client() {
200
- // See https://developers.google.com/identity/protocols/OAuth2InstalledApp#formingtheurl for more details about these fields.
201
- $config = array(
202
- 'application_name' => 'Google Analytics by Yoast',
203
- 'client_id' => '346753076522-21smrc6aq0hq8oij8001s57dfoo8igf5.apps.googleusercontent.com',
204
- 'client_secret' => '5oWaEGFgp-bSrY6vWBmdPfIF',
205
- 'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
206
- 'scopes' => array( 'https://www.googleapis.com/auth/analytics.readonly' ),
207
- );
208
-
209
- $config = apply_filters( 'yst-ga-filter-ga-config', $config );
210
-
211
- $this->client = new Yoast_Api_Google_Client( $config, 'yoast-ga', '' );
212
- }
213
-
214
- /**
215
- * Gets an authentication URL
216
- *
217
- * @return mixed
218
- */
219
- public function create_auth_url() {
220
- return $this->client->createAuthUrl();
221
- }
222
-
223
- /**
224
- * Saving profile response in options
225
- *
226
- * @param array $accounts
227
- */
228
- protected function save_profile_response( $accounts ) {
229
- $this->options['ga_api_response_accounts'] = $accounts;
230
-
231
- $this->update_options();
232
- }
233
-
234
- /**
235
- * Test a connection to Google
236
- *
237
- * @return bool
238
- */
239
- private function test_connection_to_google() {
240
- $wp_http = new WP_Http();
241
- if ( $wp_http->block_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' ) === false ) {
242
- return true;
243
- }
244
-
245
- return false;
246
- }
247
-
248
- /**
249
- * Format the accounts request
250
- *
251
- * @param array $response
252
- *
253
- * @return mixed
254
- */
255
- private function format_profile_call( $response ) {
256
-
257
- if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
258
- if ( ! empty( $response['body']['items'] ) && is_array( $response['body']['items'] ) ) {
259
- $accounts = array();
260
-
261
- foreach ( $response['body']['items'] as $item ) {
262
- // Check if webProperties is set
263
- if ( isset( $item['webProperties'] ) ) {
264
- $profiles = array();
265
-
266
- foreach ( $item['webProperties'] as $property_key => $property ) {
267
- $profiles[ $property_key ] = array(
268
- 'id' => $property['id'],
269
- 'name' => $property['name'],
270
- 'items' => array(),
271
- );
272
-
273
- // Check if profiles is set
274
- if ( isset( $property['profiles'] ) ) {
275
- foreach ( $property['profiles'] as $key => $profile ) {
276
- $profiles[ $property_key ]['items'][ $key ] = array_merge(
277
- $profile,
278
- array(
279
- 'name' => $profile['name'] . ' (' . $property['id'] . ')',
280
- 'ua_code' => $property['id'],
281
- )
282
- );
283
- }
284
- }
285
- }
286
-
287
- $accounts[ $item['id'] ] = array(
288
- 'id' => $item['id'],
289
- 'ua_code' => $property['id'],
290
- 'parent_name' => $item['name'],
291
- 'items' => $profiles,
292
- );
293
-
294
- }
295
- }
296
-
297
- return $accounts;
298
- }
299
- }
300
-
301
- return false;
302
- }
303
-
304
- /**
305
- * Doing some clean up when this method is called
306
- */
307
- private function api_cleanup() {
308
- delete_option( 'yst_ga_api_call_fail' );
309
- }
310
-
311
- }
312
-
313
- /**
314
- * Notice class.
315
- */
316
- class Yoast_Google_Analytics_Notice {
317
-
318
- /**
319
- * Throw a warning if no UA code is set.
320
- */
321
- public static function config_warning() {
322
- self::show_error(
323
- sprintf( __( 'Please configure your %sGoogle Analytics settings%s!', 'google-analytics-for-wordpress' ),
324
- '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">',
325
- '</a>'
326
- )
327
- );
328
- }
329
-
330
- /**
331
- * Throw a warning when the fetching failed
332
- */
333
- public static function warning_fetching_data_authenticate() {
334
- self::show_error(
335
- sprintf(
336
- __( 'It seems the authentication for the plugin has expired, please %sre-authenticate%s with Google Analytics to allow the plugin to fetch data.', 'google-analytics-for-wordpress' ),
337
- '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">',
338
- '</a>'
339
- )
340
- );
341
- }
342
-
343
- /**
344
- * Throw a warning when the fetching failed
345
- */
346
- public static function warning_fetching_data() {
347
- self::show_error(
348
- sprintf(
349
- __( 'Data is not up-to-date, there was an error in retrieving the data from Google Analytics. This error could be caused by several issues. If the error persists, please see %sthis page%s.', 'google-analytics-for-wordpress' ),
350
- '<a href="http://yoa.st/2p">',
351
- '</a>'
352
- )
353
- );
354
- }
355
-
356
- /**
357
- * Showing the given error as an error div
358
- *
359
- * @param string $error_message
360
- */
361
- private static function show_error( $error_message ) {
362
- echo '<div class="error"><p>' . $error_message . '</p></div>';
363
- }
364
-
365
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-googleanalytics-reporting.php DELETED
@@ -1,156 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Class Yoast_Googleanalytics_Reporting
8
- */
9
- class Yoast_Googleanalytics_Reporting {
10
-
11
- /**
12
- * Store this instance
13
- *
14
- * @var null
15
- */
16
- private static $instance = null;
17
-
18
- /**
19
- * Getting the instance object
20
- *
21
- * This method will return the instance of itself, if instance not exists, becauses of it's called for the first
22
- * time, the instance will be created.
23
- *
24
- * @return null|Yoast_Google_Analytics
25
- */
26
- public static function get_instance() {
27
- if ( is_null( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
-
31
- return self::$instance;
32
- }
33
-
34
- /**
35
- * Format a response
36
- *
37
- * @param array $raw_data
38
- * @param string $store_as
39
- * @param string $start_date
40
- * @param string $end_date
41
- *
42
- * @return array
43
- */
44
- public function parse_response( $raw_data, $store_as, $start_date, $end_date ) {
45
- $data = array();
46
-
47
- if ( $store_as == 'datelist' ) {
48
- $data_tmp = $this->date_range( strtotime( $start_date ), strtotime( $end_date ) );
49
- $data = array_keys( $data_tmp );
50
- }
51
-
52
- if ( isset( $raw_data['body']['rows'] ) && is_array( $raw_data['body']['rows'] ) ) {
53
- foreach ( $raw_data['body']['rows'] as $key => $item ) {
54
- if ( $store_as == 'datelist' ) {
55
- $data[ (int) $this->format_ga_date( $item[0] ) ] = $this->parse_row( $item );
56
- }
57
- else {
58
- $data[] = $this->parse_data_row( $item );
59
- }
60
- }
61
- }
62
-
63
- if ( $store_as == 'datelist' ) {
64
- $data = $this->check_validity_data( $data );
65
- }
66
-
67
- return $data;
68
- }
69
-
70
- /**
71
- * Check the key on valid unix timestamps and remove invalid keys
72
- *
73
- * @param array $data
74
- *
75
- * @return array
76
- */
77
- private function check_validity_data( $data = array() ) {
78
- foreach ( $data as $key => $value ) {
79
- if ( strlen( $key ) <= 5 ) {
80
- unset( $data[ $key ] );
81
- }
82
- }
83
-
84
- return $data;
85
- }
86
-
87
- /**
88
- * Format the GA date value
89
- *
90
- * @param string $date
91
- *
92
- * @return int
93
- */
94
- private function format_ga_date( $date ) {
95
- $year = substr( $date, 0, 4 );
96
- $month = substr( $date, 4, 2 );
97
- $day = substr( $date, 6, 2 );
98
-
99
- return strtotime( $year . '-' . $month . '-' . $day );
100
- }
101
-
102
- /**
103
- * Parse a row and return an array with the correct data rows
104
- *
105
- * @param array $item
106
- *
107
- * @return array
108
- */
109
- private function parse_row( $item ) {
110
- if ( isset( $item[2] ) ) {
111
- return array(
112
- 'date' => (int) $this->format_ga_date( $item[0] ),
113
- 'value' => (string) $item[1],
114
- 'total' => (int) $item[2],
115
- );
116
- }
117
-
118
- return (int) $item[1];
119
- }
120
-
121
- /**
122
- * Parse a row for the list storage type
123
- *
124
- * @param array $item
125
- *
126
- * @return array
127
- */
128
- private function parse_data_row( $item ) {
129
- return array(
130
- 'name' => (string) $item[0],
131
- 'value' => (int) $item[1],
132
- );
133
- }
134
-
135
- /**
136
- * Calculate the date range between 2 dates
137
- *
138
- * @param string $current
139
- * @param string $last
140
- * @param string $step
141
- * @param string $format
142
- *
143
- * @return array
144
- */
145
- private function date_range( $current, $last, $step = '+1 day', $format = 'Y-m-d' ) {
146
- $dates = array();
147
-
148
- while ( $current <= $last ) {
149
- $dates[] = date( $format, $current );
150
- $current = strtotime( $step, $current );
151
- }
152
-
153
- return $dates;
154
- }
155
-
156
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/class-admin-dashboards-api-options.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards API options.
8
- */
9
- class Yoast_GA_Dashboards_Api_Options {
10
-
11
- /**
12
- * Store this instance
13
- *
14
- * @var null
15
- */
16
- private static $instance = null;
17
-
18
- /**
19
- * @var string $access_token Store the access token
20
- */
21
- private $access_token;
22
-
23
- /**
24
- * @var array $options Store the options
25
- */
26
- private $options;
27
-
28
- /**
29
- * Construct on the dashboards class for GA
30
- */
31
- protected function __construct() {
32
- $this->set_options();
33
- }
34
-
35
- /**
36
- * Get the instance
37
- *
38
- * @return Yoast_GA_Dashboards
39
- */
40
- public static function get_instance() {
41
- if ( is_null( self::$instance ) ) {
42
- self::$instance = new self();
43
- }
44
-
45
- return self::$instance;
46
- }
47
-
48
- /**
49
- * Set the API options
50
- */
51
- public function set_options() {
52
- $this->options = Yoast_Google_Analytics::get_instance()->get_options();
53
-
54
- $this->set_access_token();
55
- }
56
-
57
- /**
58
- * Set the access token if we have one
59
- */
60
- private function set_access_token() {
61
- if ( isset( $this->options['ga_oauth']['access_token']['oauth_token'] ) && isset( $this->options['ga_oauth']['access_token']['oauth_token_secret'] ) ) {
62
- $this->access_token = $this->options['ga_oauth']['access_token'];
63
- }
64
- }
65
-
66
- /**
67
- * Get the API options
68
- *
69
- * @return mixed
70
- */
71
- public function get_options() {
72
- return $this->options;
73
- }
74
-
75
- /**
76
- * Get the access token from the options API, false on fail
77
- *
78
- * @return bool
79
- */
80
- public function get_access_token() {
81
- if ( ! empty( $this->access_token ) ) {
82
- return $this->access_token;
83
- }
84
- else {
85
- return false;
86
- }
87
- }
88
-
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/class-admin-dashboards-collector.php DELETED
@@ -1,464 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards collector.
8
- */
9
- class Yoast_GA_Dashboards_Collector {
10
-
11
- /**
12
- * @var array $active_metrics Store the active metrics
13
- */
14
- public $active_metrics;
15
-
16
- /**
17
- * Store the dimensions
18
- *
19
- * @var array
20
- */
21
- private $dimensions = array();
22
-
23
- /**
24
- * Store the valid metrics, which should be
25
- *
26
- * @var array
27
- */
28
- private $valid_metrics = array();
29
-
30
- /**
31
- * @var integer $ga_profile_id Store the GA Profile ID
32
- */
33
- public $ga_profile_id;
34
-
35
- /**
36
- * Construct on the dashboards class for GA
37
- *
38
- * @param int $ga_profile_id
39
- * @param array $active_metrics
40
- * @param array $valid_metrics
41
- */
42
- public function __construct( $ga_profile_id, $active_metrics, $valid_metrics ) {
43
- $this->ga_profile_id = $ga_profile_id;
44
-
45
- $active_metrics = $this->filter_metrics_to_dimensions( $active_metrics );
46
- $this->active_metrics = $active_metrics;
47
-
48
- add_filter( 'ga_dashboards_dimensions', array( $this, 'filter_dimensions' ), 10, 1 );
49
-
50
- $this->options = Yoast_GA_Dashboards_Api_Options::get_instance();
51
-
52
- $this->init_shutdown_hook();
53
- }
54
-
55
- /**
56
- * Fetch the data from Google Analytics and store it
57
- */
58
- public function aggregate_data() {
59
- if ( ! empty ( $this->ga_profile_id ) && is_numeric( $this->ga_profile_id ) ) {
60
- // ProfileID is set
61
-
62
- /**
63
- * Implement the metric data first
64
- */
65
- if ( is_array( $this->active_metrics ) && count( $this->active_metrics ) >= 1 ) {
66
- $this->aggregate_metrics( $this->active_metrics );
67
- }
68
-
69
- /**
70
- * Now implement the dimensions that are set
71
- */
72
- if ( is_array( $this->dimensions ) && count( $this->dimensions ) >= 1 ) {
73
- $this->aggregate_dimensions( $this->dimensions );
74
- }
75
- }
76
- else {
77
- // Failure on authenticating, please reauthenticate
78
- }
79
- }
80
-
81
- /**
82
- * This hook runs on the shutdown to fetch data from GA
83
- */
84
- private function init_shutdown_hook() {
85
- // Hook the WP cron event
86
- add_action( 'wp', array( $this, 'setup_wp_cron_aggregate' ) );
87
-
88
- // Hook our function to the WP cron event the fetch data daily
89
- add_action( 'yst_ga_aggregate_data', array( $this, 'aggregate_data' ) );
90
-
91
- // Check if the WP cron did run on time
92
- if ( filter_input( INPUT_GET, 'page' ) === 'yst_ga_dashboard' ) {
93
- add_action( 'shutdown', array( $this, 'check_api_call_hook' ) );
94
- }
95
- }
96
-
97
- /**
98
- * Check if we scheduled the WP cron event, if not, do so.
99
- */
100
- public function setup_wp_cron_aggregate() {
101
- if ( ! wp_next_scheduled( 'yst_ga_aggregate_data' ) ) {
102
- // Set the next event of fetching data
103
- wp_schedule_event( strtotime( date( 'Y-m-d', strtotime( 'tomorrow' ) ) . ' 00:05:00 ' ), 'daily', 'yst_ga_aggregate_data' );
104
- }
105
- }
106
-
107
- /**
108
- * Check if the WP cron did run yesterday. If not, we need to run it form here
109
- */
110
- public function check_api_call_hook() {
111
- $last_run = $this->get_last_aggregate_run();
112
-
113
-
114
- /**
115
- * Transient doesn't exists, so we need to run the
116
- * hook (This function runs already on Shutdown so
117
- * we can call it directly from now on) or the last run has ben more than 24 hours
118
- */
119
- if ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 24 ) {
120
- $this->aggregate_data();
121
- }
122
- }
123
-
124
-
125
- /**
126
- * Get the datetime when the aggregate data function was succesful
127
- *
128
- * @return mixed
129
- */
130
- private function get_last_aggregate_run() {
131
- return get_option( 'yst_ga_last_wp_run' );
132
- }
133
-
134
- /**
135
- * Remove metrics and set them as a dimension if needed
136
- *
137
- * @param array $metrics
138
- *
139
- * @return mixed
140
- */
141
- private function filter_metrics_to_dimensions( $metrics ) {
142
- $filter_metrics = $this->get_filter_metrics();
143
-
144
- foreach ( $metrics as $key => $metric_name ) {
145
- if ( isset( $filter_metrics[ $metric_name ] ) ) {
146
- // Add and set the dimension
147
- $dimension = array( $filter_metrics[ $metric_name ] );
148
- $this->dimensions = array_merge( $this->dimensions, $dimension );
149
-
150
- // Remove it from the metrics after we've added it into dimensions
151
- unset( $metrics[ $key ] );
152
- }
153
- }
154
-
155
- return $metrics;
156
- }
157
-
158
- /**
159
- * Get array with metrics which we need to filter as a dimension
160
- *
161
- * @return array
162
- */
163
- private function get_filter_metrics() {
164
- return array(
165
- 'source' => array(
166
- 'metric' => 'sessions',
167
- 'dimension' => 'source',
168
- 'storage_name' => 'source',
169
- ),
170
- 'top_pageviews' => array(
171
- 'metric' => 'pageViews',
172
- 'dimension' => 'pagePath',
173
- 'storage_name' => 'top_pageviews',
174
- ),
175
- 'top_countries' => array(
176
- 'metric' => 'sessions',
177
- 'dimension' => 'country',
178
- 'storage_name' => 'top_countries',
179
- ),
180
- );
181
- }
182
-
183
- /**
184
- * Filter function for adding dimensions
185
- *
186
- * @filter ga_dashboards_dimensions
187
- *
188
- * @param array $dimensions
189
- *
190
- * @return array
191
- */
192
- public function filter_dimensions( $dimensions = array() ) {
193
- if ( is_array( $dimensions ) && count( $dimensions ) >= 1 ) {
194
- $dimensions = array_merge( $this->dimensions, $dimensions );
195
- $this->dimensions = $dimensions;
196
- }
197
-
198
- return $this->dimensions;
199
- }
200
-
201
- /**
202
- * Get the start and and date for aggregation functionality
203
- *
204
- * @return array
205
- */
206
- private function get_date_range() {
207
- /**
208
- * Filter: 'yst-ga-filter-api-end-date' - Allow people to change the end date for the dashboard
209
- * data. Default: yesterday.
210
- *
211
- * @api string Date (Y-m-d)
212
- */
213
- return array(
214
- 'start' => date( 'Y-m-d', strtotime( '-1 month' ) ),
215
- 'end' => apply_filters( 'yst-ga-filter-api-end-date', date( 'Y-m-d', strtotime( 'yesterday' ) ) ),
216
- );
217
- }
218
-
219
- /**
220
- * Aggregate metrics from GA. This function should be called in the shutdown function.
221
- *
222
- * @param array $metrics
223
- */
224
- private function aggregate_metrics( $metrics ) {
225
- $dates = $this->get_date_range();
226
-
227
- foreach ( $metrics as $metric ) {
228
- $this->execute_call( $metric, $dates['start'], $dates['end'] );
229
- }
230
- }
231
-
232
- /**
233
- * Aggregate dimensions from GA. This function should be called in the shutdown function.
234
- *
235
- * @param array $dimensions
236
- */
237
- private function aggregate_dimensions( $dimensions ) {
238
- $dates = $this->get_date_range();
239
-
240
- foreach ( $dimensions as $dimension ) {
241
- if ( isset( $dimension['metric'] ) ) {
242
- if ( isset( $dimension['id'] ) ) {
243
- $this->execute_call( $dimension['metric'], $dates['start'], $dates['end'], 'ga:dimension' . $dimension['id'] );
244
- }
245
- elseif ( isset( $dimension['dimension'] ) ) {
246
- if ( isset( $dimension['storage_name'] ) ) {
247
- $this->execute_call( $dimension['metric'], $dates['start'], $dates['end'], 'ga:' . $dimension['dimension'], $dimension['storage_name'] );
248
- }
249
- else {
250
- $this->execute_call( $dimension['metric'], $dates['start'], $dates['end'], 'ga:' . $dimension['dimension'] );
251
- }
252
- }
253
- }
254
- }
255
- }
256
-
257
- /**
258
- * Execute an API call to Google Analytics and store the data in the dashboards data class
259
- *
260
- * @param string $metric
261
- * @param string $start_date 2014-10-16
262
- * @param string $end_date 2014-11-20
263
- * @param string $dimensions ga:date
264
- * @param string $storage_name auto
265
- *
266
- * @return bool
267
- */
268
- private function execute_call( $metric, $start_date, $end_date, $dimensions = 'ga:date', $storage_name = 'auto' ) {
269
- $dimensions = $this->prepare_dimensions( $dimensions, $metric );
270
- $params = $this->build_params_for_call( $start_date, $end_date, $dimensions, $metric );
271
- $storage_type = $this->get_storage_type( $dimensions );
272
-
273
- $response = Yoast_Google_Analytics::get_instance()->do_request( 'https://www.googleapis.com/analytics/v3/data/ga?' . $params );
274
-
275
- if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
276
-
277
- // Delete option api_fail because there it's successful now
278
- delete_option( 'yst_ga_api_call_fail' );
279
-
280
- // Success, set a transient which stores the latest runtime
281
- update_option( 'yst_ga_last_wp_run', date( 'Y-m-d' ) );
282
-
283
- $response = Yoast_Googleanalytics_Reporting::get_instance()->parse_response( $response, $storage_type, $start_date, $end_date );
284
- }
285
- else {
286
- // When response is failing, we should count the number of
287
- $this->save_api_failure();
288
-
289
- return false;
290
- }
291
-
292
- if ( strpos( 'ga:date', $dimensions ) !== false ) {
293
- return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'datelist', $storage_name );
294
- }
295
- else {
296
- return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'table', $storage_name );
297
- }
298
- }
299
-
300
- /**
301
- * When the API isn't able to get a successful response (code 200), we have to save that the call has failed
302
- */
303
- private function save_api_failure() {
304
- update_option( 'yst_ga_api_call_fail', true );
305
- }
306
-
307
- /**
308
- * Get the storage type from dimensions
309
- *
310
- * @param string $dimensions
311
- *
312
- * @return string
313
- */
314
- private function get_storage_type( $dimensions ) {
315
- if ( strpos( 'ga:date', $dimensions ) !== false ) {
316
- return 'datelist';
317
- }
318
- else {
319
- return 'table';
320
- }
321
- }
322
-
323
- /**
324
- * Prepare dimensions before adding them as a parameter in a call
325
- *
326
- * @param array $dimensions
327
- * @param array $metric
328
- *
329
- * @return array
330
- */
331
- private function prepare_dimensions( $dimensions, $metric ) {
332
- $filter_metrics = $this->get_filter_metrics();
333
-
334
- // Check if the dimensions param is an array, if so, glue it with implode to a comma separated string.
335
- if ( is_array( $dimensions ) ) {
336
- $dimensions = implode( ',', $dimensions );
337
- }
338
-
339
- if ( in_array( $metric, $this->valid_metrics ) ) {
340
- $dimensions = 'ga:date,' . $dimensions;
341
- }
342
- elseif ( isset( $filter_metrics[ str_replace( 'ga:', '', $dimensions ) ] ) ) {
343
- // Make sure we don't have a ga:date property here
344
- $dimensions = str_replace( 'ga:date', '', $dimensions );
345
- }
346
-
347
- return $dimensions;
348
- }
349
-
350
- /**
351
- * Build the params for a call to Google Analytics, return them prepared for a http query
352
- *
353
- * @param string $start_date
354
- * @param string $end_date
355
- * @param string $dimensions
356
- * @param string $metric
357
- *
358
- * @return string
359
- */
360
- private function build_params_for_call( $start_date, $end_date, $dimensions, $metric ) {
361
- /**
362
- * Filter: 'yst-ga-filter-api-limit' - Allow people to change the max results value in the API
363
- * calls. Default value is 1000 results per call.
364
- *
365
- * @api int 1000
366
- */
367
- $api_call_limit = apply_filters( 'yst-ga-filter-api-limit', 1000 );
368
-
369
- $params = array(
370
- 'ids' => 'ga:' . $this->ga_profile_id,
371
- 'start-date' => $start_date,
372
- 'end-date' => $end_date,
373
- 'dimensions' => $dimensions,
374
- 'metrics' => 'ga:' . $metric,
375
- 'max-results' => $api_call_limit,
376
- );
377
-
378
- $params = $this->add_sort_direction( $params, $dimensions, $metric );
379
- $params = http_build_query( $params );
380
-
381
- return $params;
382
- }
383
-
384
- /**
385
- * Add a sort direction if we need to (Especially on dimensions which are
386
- * listed in $this->get_filter_metrics())
387
- *
388
- * @param array $params
389
- * @param string $dimensions
390
- * @param string $metric
391
- *
392
- * @return array
393
- */
394
- private function add_sort_direction( $params, $dimensions, $metric ) {
395
- $filter_dimensions = $this->get_filter_metrics();
396
-
397
- foreach ( $filter_dimensions as $dimension ) {
398
- if ( str_replace( 'ga:', '', $dimensions ) == $dimension['dimension'] && str_replace( 'ga:', '', $metric ) == $dimension['metric'] ) {
399
- $params['sort'] = '-ga:' . $dimension['metric'];
400
- }
401
- }
402
-
403
- return $params;
404
- }
405
-
406
- /**
407
- * Handle the response from the Google Analytics api.
408
- *
409
- * @param array|boolean $response
410
- * @param string $metric
411
- * @param array $dimensions
412
- * @param string $start_date
413
- * @param string $end_date
414
- * @param string $store_as
415
- * @param string $storage_name
416
- *
417
- * @return bool
418
- */
419
- private function handle_response( $response, $metric, $dimensions, $start_date, $end_date, $store_as = 'table', $storage_name = 'auto' ) {
420
- if ( is_array( $response ) ) {
421
- // Success, store this data
422
- $filter_metrics = $this->get_filter_metrics();
423
- $extracted = str_replace( 'ga:', '', str_replace( 'ga:date,', '', $dimensions ) );
424
-
425
- if ( isset( $filter_metrics[ $extracted ] ) ) {
426
- $name = $extracted;
427
- }
428
- else {
429
- $name = $metric;
430
- }
431
-
432
- if ( $dimensions !== 'ga:date' && ! isset( $filter_metrics[ $extracted ] ) ) {
433
- $name = str_replace( 'ga:date,', '', $dimensions );
434
- }
435
-
436
- // Overwrite the name if we have a defined one
437
- if ( $storage_name != 'auto' ) {
438
- $name = $storage_name;
439
- }
440
-
441
- return Yoast_GA_Dashboards_Data::set( $name, $response, strtotime( $start_date ), strtotime( $end_date ), $store_as );
442
- }
443
- else {
444
- // Failure on API call try to log it
445
- $this->log_error( print_r( $response, true ) );
446
-
447
- return false;
448
- }
449
- }
450
-
451
- /**
452
- * Log an error while calling the Google Analytics API
453
- *
454
- * @param string $error
455
- */
456
- private function log_error( $error ) {
457
- if ( true == WP_DEBUG ) {
458
- if ( function_exists( 'error_log' ) ) {
459
- error_log( 'Google Analytics by MonsterInsights (Dashboard API): ' . $error );
460
- }
461
- }
462
- }
463
-
464
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/class-admin-dashboards-data.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * This class is used to store and get the data of the dashboards. The data is aggregated by
8
- * the class-admin-dashboards-collector.php and saved with Yoast_GA_Dashboards_Data::set().
9
- *
10
- * You can retrieve the data by using the function Yoast_GA_Dashboards_Data::get() in this
11
- * class.
12
- */
13
- class Yoast_GA_Dashboards_Data {
14
-
15
- /**
16
- * Get a data object
17
- *
18
- * @param string $type
19
- *
20
- * @return array
21
- */
22
- public static function get( $type ) {
23
- $option = get_option( 'yst_ga_' . $type );
24
-
25
- if ( false === $option ) {
26
- // Option does not exist, abort
27
- return array();
28
- }
29
-
30
- // @TODO loop through transient to get the correct date range
31
-
32
- return $option;
33
- }
34
-
35
- /**
36
- * Save a data object
37
- *
38
- * @param string $type
39
- * @param array $value
40
- * @param string $start_date
41
- * @param string $end_date
42
- * @param string $store_as
43
- *
44
- * @return bool
45
- */
46
- public static function set( $type, $value, $start_date, $end_date, $store_as ) {
47
- $store = array(
48
- 'store_as' => $store_as,
49
- 'type' => $type,
50
- 'start_date' => $start_date,
51
- 'end_date' => $end_date,
52
- 'value' => $value,
53
- );
54
-
55
- return update_option( 'yst_ga_' . $type, $store );
56
- }
57
-
58
- /**
59
- * Reset an option of the GA dashboards storage engine
60
- *
61
- * @param string $type
62
- *
63
- * @return bool
64
- */
65
- public static function reset( $type ) {
66
- return update_option( 'yst_ga_' . $type, array() );
67
- }
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/class-admin-dashboards-display.php DELETED
@@ -1,142 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards display class.
8
- */
9
- class Yoast_GA_Dashboards_Display {
10
-
11
- /**
12
- * Property for holding instance of itself
13
- *
14
- * @var Yoast_GA_Dashboards_Display
15
- */
16
- protected static $instance;
17
-
18
- /**
19
- * Container for holding the setted dashboards
20
- *
21
- * @var array
22
- */
23
- protected $dashboards = array();
24
-
25
- /**
26
- * @var array The dashboard types which can be used
27
- */
28
- protected $dashboard_types = array( 'graph', 'table' );
29
-
30
- /**
31
- * @var array For each dashboard type there will be created a driver that will be stored in this property
32
- */
33
- protected $drivers = array();
34
-
35
- /**
36
- * For the use of singleton pattern. Create instance of itself and return his instance
37
- *
38
- * @return Yoast_GA_Dasboards_Graph
39
- */
40
- public static function get_instance() {
41
-
42
- if ( is_null( self::$instance ) ) {
43
- self::$instance = new self();
44
- }
45
-
46
- return self::$instance;
47
- }
48
-
49
- /**
50
- * Protected constructor to prevent creating a new instance of the
51
- * *Singleton* via the `new` operator from outside of this class.
52
- */
53
- protected function __construct() {
54
- foreach ( $this->dashboard_types as $dashboard_type ) {
55
- if ( ! $this->driver_exists( $dashboard_type ) ) {
56
- $this->create_driver( $dashboard_type );
57
- }
58
- }
59
- }
60
-
61
- /**
62
- * Get the driver from property, this->drivers
63
- *
64
- * If driver doesn't exist, it will be created first
65
- *
66
- * @param string $dashboard_type - The name of the driver that will be returned
67
- *
68
- * @return object
69
- */
70
- private function driver( $dashboard_type ) {
71
-
72
- if ( ! $this->driver_exists( $dashboard_type ) ) {
73
- $this->create_driver( $dashboard_type );
74
- }
75
-
76
- return $this->drivers[ $dashboard_type ];
77
- }
78
-
79
- /**
80
- * Adding dashboards to $this->dashboard en register them to the driver by $this->register
81
- *
82
- * @param array $dashboards
83
- */
84
- public function add_dashboards( $dashboards ) {
85
- // Save all dashboards to property - for future use
86
- $this->dashboards = array_merge( $this->dashboards, $dashboards );
87
-
88
- $this->register( $dashboards );
89
- }
90
-
91
- /**
92
- * Register dashboards to the drivers
93
- *
94
- * @param array $dashboards
95
- */
96
- private function register( $dashboards ) {
97
- foreach ( $dashboards as $dashboard_name => $dashboard_settings ) {
98
- if ( ! empty( $dashboard_settings['type'] ) ) {
99
- $this->driver( $dashboard_settings['type'] )->register( $dashboard_name, $dashboard_settings );
100
- }
101
- }
102
- }
103
-
104
- /**
105
- * Displaying the $dashboards on the screen. If $dashboards isn't given it will display all registered
106
- * dashboards
107
- *
108
- * @param string $tab_to_show
109
- */
110
- public function display( $tab_to_show ) {
111
-
112
- $dashboards_to_show = $this->dashboards;
113
-
114
- foreach ( $dashboards_to_show as $dashboard_name => $dashboard_settings ) {
115
- if ( ! empty( $dashboard_settings['tab'] ) && $dashboard_settings['tab'] === $tab_to_show ) {
116
- $this->driver( $dashboard_settings['type'] )->display( $dashboard_name );
117
- }
118
- }
119
- }
120
-
121
- /**
122
- * Check if given $dashboard_type exists and if it's an object
123
- *
124
- * @param string $dashboard_type
125
- *
126
- * @return bool
127
- */
128
- protected function driver_exists( $dashboard_type ) {
129
- return array_key_exists( $dashboard_type, $this->drivers ) && is_object( $this->drivers[ $dashboard_type ] );
130
- }
131
-
132
- /**
133
- * Creates a driver based on given $dashboard_type
134
- *
135
- * @param string $dashboard_type
136
- */
137
- protected function create_driver( $dashboard_type ) {
138
- $driver_class = 'Yoast_GA_Dashboards_' . ucfirst( $dashboard_type );
139
- $this->drivers[ $dashboard_type ] = new $driver_class();
140
- }
141
-
142
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/class-admin-dashboards.php DELETED
@@ -1,253 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards class.
8
- */
9
- class Yoast_GA_Dashboards {
10
-
11
- /**
12
- * @var Yoast_GA_Dashboards_Collector $aggregator Store the data aggregator
13
- */
14
- public $aggregator;
15
-
16
- /**
17
- * @var array $data Store the Data instance
18
- */
19
- public $data;
20
-
21
- /**
22
- * @var array $active_metrics Store the active metrics
23
- */
24
- public $active_metrics;
25
-
26
- /**
27
- * Store the valid metrics which are available in the Google API, more can be added
28
- *
29
- * @var array
30
- *
31
- * @link https://ga-dev-tools.appspot.com/explorer/
32
- */
33
- private $valid_metrics = array( 'sessions', 'bounces', 'users', 'newUsers', 'percentNewSessions', 'bounceRate', 'sessionDuration', 'avgSessionDuration', 'hits' );
34
-
35
- /**
36
- * Store this instance
37
- *
38
- * @var null
39
- */
40
- private static $instance = null;
41
-
42
- /**
43
- * @var boolean $dashboards_disabled Store the Dashboards disabled bool
44
- */
45
- private $dashboards_disabled;
46
-
47
- /**
48
- * Construct on the dashboards class for GA
49
- */
50
- protected function __construct() {
51
- add_filter( 'ga_extend_dashboards', array( $this, 'extend_dashboards' ), 10, 1 );
52
-
53
- $this->dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
54
- }
55
-
56
- /**
57
- * Init the dashboards
58
- *
59
- * @param integer $ga_profile_id
60
- */
61
- public function init_dashboards( $ga_profile_id ) {
62
- if ( ! $this->dashboards_disabled ) {
63
- $dashboards = $this->get_default_dashboards();
64
-
65
- $this->extend_dashboards( $dashboards );
66
-
67
- // Register the active metrics
68
- $register = array_keys( $dashboards );
69
-
70
- $this->aggregator = new Yoast_GA_Dashboards_Collector( $ga_profile_id, $register, $this->valid_metrics );
71
-
72
- $this->register( $register );
73
- }
74
- }
75
-
76
- /**
77
- * Adding dashboards for front-end
78
- *
79
- * By hook as filter: $dashboards = apply_filters( 'ga_extend_dashboards', $dashboards);
80
- *
81
- * @param array $dashboards
82
- *
83
- * @return mixed
84
- */
85
- public function extend_dashboards( $dashboards ) {
86
- // Initialize the dashboard graphs
87
- Yoast_GA_Dashboards_Display::get_instance()->add_dashboards( $dashboards );
88
-
89
- return $dashboards;
90
- }
91
-
92
- /**
93
- * Get the instance
94
- *
95
- * @return Yoast_GA_Dashboards
96
- */
97
- public static function get_instance() {
98
- if ( is_null( self::$instance ) ) {
99
- self::$instance = new self();
100
- }
101
-
102
- return self::$instance;
103
- }
104
-
105
- /**
106
- * Register the dashboard types
107
- *
108
- * @param array|string $types
109
- *
110
- * @return bool
111
- */
112
- public function register( $types ) {
113
- if ( is_array( $types ) == false ) {
114
- $types = array( $types );
115
- }
116
-
117
- if ( is_array( $types ) && count( $types ) >= 1 ) {
118
- if ( $this->validate_dashboard_types( $types ) ) {
119
- $this->active_metrics = $types;
120
-
121
- return true;
122
- }
123
- }
124
-
125
- return false;
126
- }
127
-
128
- /**
129
- * Adding translations to ga-admin-dashboard
130
- */
131
- public function add_dashboard_js_translations() {
132
- // Now we can localize the script with our data.
133
- $translation_array = array(
134
- // For datatables
135
- 'sort_ascending' => __( ': activate to sort column ascending', 'google-analytics-for-wordpress' ),
136
- 'sort_descending' => __( ': activate to sort column descending', 'google-analytics-for-wordpress' ),
137
- 'empty_table' => __( 'No data available', 'google-analytics-for-wordpress' ),
138
- 'info' => _x( 'Showing _START_ to _END_ of _TOTAL_ rows', '_START_, _END_ and _TOTAL_ will be replaced by JS (See: http://datatables.net/reference/option/language.info)', 'google-analytics-for-wordpress' ),
139
- 'info_empty' => __( 'No rows to show', 'google-analytics-for-wordpress' ),
140
- 'info_filtered' => _x( '(filtered from _MAX_ total rows)', '_MAX_ will be replaced by JS (See: http://datatables.net/reference/option/language.infoFiltered)', 'google-analytics-for-wordpress' ),
141
- 'length_menu' => _x( 'Show _MENU_ rows', '_MAX_ will be replaced by JS', 'google-analytics-for-wordpress' ),
142
- 'loading_records' => __( 'Loading...', 'google-analytics-for-wordpress' ),
143
- 'pagination_first' => __( 'First', 'google-analytics-for-wordpress' ),
144
- 'pagination_last' => __( 'Last', 'google-analytics-for-wordpress' ),
145
- 'pagination_next' => __( 'Next', 'google-analytics-for-wordpress' ),
146
- 'pagination_previous' => __( 'Previous', 'google-analytics-for-wordpress' ),
147
- 'processing' => __( 'Processing...', 'google-analytics-for-wordpress' ),
148
- 'search_placeholder' => __( 'Search', 'google-analytics-for-wordpress' ),
149
- 'zero_records' => __( 'No matching records found', 'google-analytics-for-wordpress' ),
150
-
151
- // For dimensions
152
- 'dimensions' => __( 'Reports', 'google-analytics-for-wordpress' ),
153
- 'custom_dimensions' => __( 'Custom dimension reports', 'google-analytics-for-wordpress' ),
154
- );
155
-
156
- wp_localize_script( 'ga-admin-dashboard', 'dashboard_translate', $translation_array );
157
- }
158
-
159
- /**
160
- * Reset all dashboards data by removing the options of the registered dashboards
161
- *
162
- * @return bool
163
- */
164
- public function reset_dashboards_data() {
165
- if ( ! $this->dashboards_disabled ) {
166
- $dashboards = $this->get_default_dashboards();
167
-
168
- if ( is_array( $dashboards ) && count( $dashboards ) >= 1 ) {
169
- foreach ( $dashboards as $name => $board ) {
170
- Yoast_GA_Dashboards_Data::reset( $name );
171
- }
172
-
173
- // Make sure we fetch new data if we enable the dashboards by updating the last_run option
174
- update_option( 'yst_ga_last_wp_run', date( 'Y-m-d', strtotime( '-2 days' ) ) );
175
-
176
- return true;
177
- }
178
- }
179
-
180
- return false;
181
- }
182
-
183
- /**
184
- * Get the defaults dashboard array to register
185
- *
186
- * @return array
187
- */
188
- private function get_default_dashboards() {
189
- return array(
190
- 'sessions' => array(
191
- 'title' => __( 'Sessions', 'google-analytics-for-wordpress' ),
192
- 'help' => __( 'A session is a group of interactions that take place on your website within a given time frame. For example a single session can contain multiple screen or page views, events, social interactions, and ecommerce transactions. <a href="http://yoa.st/gasessions" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
193
- 'type' => 'graph',
194
- 'tab' => 'general',
195
- ),
196
- 'bounceRate' => array(
197
- 'title' => __( 'Bounce rate', 'google-analytics-for-wordpress' ),
198
- 'help' => __( 'Bounce Rate is the percentage of single-page sessions (i.e. sessions in which the person left your site from the entrance page without interacting with the page). <a href="http://yoa.st/gabounce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
199
- 'data-percent' => true,
200
- 'type' => 'graph',
201
- 'tab' => 'general',
202
- ),
203
- 'source' => array(
204
- 'title' => __( 'Traffic sources', 'google-analytics-for-wordpress' ),
205
- 'help' => __( 'Every referral to a web site has an origin, or (traffic) source. Possible sources include: “google” (the name of a search engine), “facebook.com” (the name of a referring site), “spring_newsletter” (the name of one of your newsletters), and “direct” (users that typed your URL directly into their browser, or who had bookmarked your site). <a href="http://yoa.st/gabnce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
206
- 'type' => 'table',
207
- 'columns' => array(
208
- __( 'Sessions', 'google-analytics-for-wordpress' )
209
- ),
210
- 'tab' => 'dimensions',
211
- ),
212
- 'top_pageviews' => array(
213
- 'title' => __( 'Popular pages', 'google-analytics-for-wordpress' ),
214
- 'help' => __( 'Pages by url.', 'google-analytics-for-wordpress' ),
215
- 'type' => 'table',
216
- 'columns' => array(
217
- __( 'Sessions', 'google-analytics-for-wordpress' )
218
- ),
219
- 'tab' => 'dimensions',
220
- ),
221
- 'top_countries' => array(
222
- 'title' => __( 'Countries', 'google-analytics-for-wordpress' ),
223
- 'help' => __( 'The country or territory from which visits originated. <a href="http://yoa.st/gacountry" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
224
- 'type' => 'table',
225
- 'columns' => array(
226
- __( 'Sessions', 'google-analytics-for-wordpress' )
227
- ),
228
- 'tab' => 'dimensions',
229
- ),
230
- );
231
- }
232
-
233
- /**
234
- * Validate the registered types of dashboards
235
- *
236
- * @param array $types
237
- *
238
- * @return bool
239
- */
240
- private function validate_dashboard_types( $types ) {
241
- $valid = true;
242
-
243
- if ( is_array( $types ) ) {
244
- foreach ( $types as $check_type ) {
245
- if ( ! in_array( $check_type, $this->valid_metrics ) ) {
246
- $valid = false;
247
- }
248
- }
249
- }
250
-
251
- return $valid;
252
- }
253
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-driver-generate.php DELETED
@@ -1,150 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Base abstract class.
8
- */
9
- abstract class Yoast_GA_Dashboards_Driver_Generate {
10
-
11
- /**
12
- * @var string - Which type of data should be loaded
13
- */
14
- protected $graph_type;
15
-
16
- /**
17
- * @var string - For which period should the data be shown
18
- */
19
- protected $period;
20
-
21
- /**
22
- * @var string - The end date
23
- */
24
- protected $end_date;
25
-
26
- /**
27
- * @var string - The start date
28
- */
29
- protected $start_date;
30
-
31
- /**
32
- * Construct will set all values and generate the date for response
33
- */
34
- public function __construct() {
35
- $this->set_graph_type();
36
- $this->set_period();
37
- $this->set_end_date();
38
- $this->set_start_date();
39
- }
40
-
41
- /**
42
- * Getting graph_id from post and strip HTML-prefix graph- to get the type
43
- */
44
- protected function set_graph_type() {
45
- $graph_id = filter_input( INPUT_GET, 'graph_id' );
46
- $graph_type = str_replace( array( 'graph-', 'table-' ), '', $graph_id );
47
- $this->graph_type = $graph_type;
48
- }
49
-
50
- /**
51
- * Getting the period from post
52
- */
53
- protected function set_period() {
54
- $this->period = filter_input( INPUT_GET, 'period' );
55
- }
56
-
57
- /**
58
- * Setting the end date
59
- */
60
- protected function set_end_date() {
61
- $this->end_date = time();
62
- }
63
-
64
- /**
65
- * This method will set a start_date based on $this->period
66
- *
67
- * The values in dropdown, that will be mapped in strtotime
68
- * See: http://php.net/manual/en/datetime.formats.relative.php
69
- */
70
- protected function set_start_date() {
71
-
72
- switch ( $this->period ) {
73
- case 'lastweek' :
74
- $time = '-6 days';
75
- break;
76
- default:
77
- case 'lastmonth' :
78
- $time = '-1 month';
79
- break;
80
- }
81
-
82
- $start_date = strtotime( $time, $this->end_date );
83
-
84
- $this->start_date = $start_date;
85
- }
86
-
87
- /**
88
- * Getting the saved Google data
89
- *
90
- * @return array
91
- */
92
- protected function get_google_data() {
93
-
94
- $response = Yoast_GA_Dashboards_Data::get( $this->graph_type );
95
-
96
- if ( $response != array() && array_key_exists( 'body', $response['value'] ) ) {
97
- $return = $response['value']['body'];
98
- }
99
- else {
100
- $return = $response;
101
- }
102
-
103
- return $this->filter_google_data( $return );
104
- }
105
-
106
- /**
107
- * Check if given timestamp is in given period
108
- *
109
- * @param integer $timestamp
110
- *
111
- * @return bool
112
- */
113
- protected function is_date_in_period( $timestamp ) {
114
- return ( $timestamp >= $this->start_date && $timestamp <= $this->end_date );
115
- }
116
-
117
- /**
118
- * Escape the data array before output
119
- *
120
- * @param array $data The data array that we need to check
121
- *
122
- * @return array|boolean The data array which is escaped
123
- */
124
- protected function escape_strings_array( $data ) {
125
- if ( is_array( $data ) ) {
126
- foreach ( $data as $key => $value ) {
127
- if ( is_array( $value ) ) {
128
- foreach ( $value as $subkey => $subvar ) {
129
- $data[ $key ][ $subkey ] = esc_html( $subvar );
130
- }
131
- }
132
- else {
133
- $data[ $key ] = esc_html( (string) $value );
134
- }
135
- }
136
-
137
- return $data;
138
- }
139
-
140
- return false;
141
- }
142
-
143
- /**
144
- * Should always be available
145
- *
146
- * @return mixed
147
- */
148
- abstract public function get_json();
149
-
150
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-driver.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Base abstract class.
8
- */
9
- abstract class Yoast_GA_Dashboards_Driver {
10
-
11
- /**
12
- * Container for holding set dashboards
13
- *
14
- * @var array
15
- */
16
- protected $dashboards = array();
17
-
18
- /**
19
- * This will initialize the AJAX request
20
- */
21
- public function __construct() {
22
- $this->initialize_ajax();
23
- }
24
-
25
- /**
26
- * Method which will be called by AJAX
27
- *
28
- * Will echo json for graph
29
- */
30
- public function get_ajax_data() {
31
- check_ajax_referer( 'yoast-ga-dashboard-nonce', '_ajax_nonce' );
32
-
33
- $generator = $this->get_dashboard_generate_object();
34
- $json = $generator->get_json();
35
-
36
- echo $json;
37
- die();
38
- }
39
-
40
- /**
41
- * Register a dashboard with settings.
42
- *
43
- * Dashboard can contain multiple dashboard-types. If so, $values shouldn't be passed and $dashboard argument
44
- * should be key->value, key = dashboard and value should contain the values
45
- *
46
- * Given arguments will be marge with objects property dashboards
47
- *
48
- * @param mixed $dashboard
49
- * @param mixed $values
50
- */
51
- public function register( $dashboard, $values = false ) {
52
-
53
- if ( ! is_array( $dashboard ) ) {
54
- $dashboard = array( $dashboard => $values );
55
- }
56
-
57
- $this->dashboards = array_merge( $this->dashboards, $dashboard );
58
- }
59
-
60
- /**
61
- * Giving the dashboardname to show
62
- *
63
- * @param string $dashboard
64
- */
65
- public function display( $dashboard ) {
66
- $settings = $this->dashboards[ $dashboard ];
67
- require dirname( GAWP_FILE ) . '/admin/dashboards/views/' . $this->dashboard_type . '.php';
68
- }
69
-
70
- /**
71
- * Setting hook for doing ajax request
72
- */
73
- protected function initialize_ajax() {
74
- add_action( $this->ajax_hook, array( $this, 'get_ajax_data' ) );
75
- }
76
-
77
- /**
78
- * This method should always be available
79
- * @return mixed
80
- */
81
- abstract protected function get_dashboard_generate_object();
82
-
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-graph-generate.php DELETED
@@ -1,154 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Graph inherited class.
8
- */
9
- class Yoast_GA_Dashboards_Graph_Generate extends Yoast_GA_Dashboards_Driver_Generate {
10
-
11
- /**
12
- * The field that will be used for displaying on x-axis. Mostly it will be the j (day in month)
13
- *
14
- * See: http://nl3.php.net/manual/en/function.date.php under 'format'
15
- *
16
- * @var string
17
- */
18
- private $date_field = 'j';
19
-
20
- /**
21
- * @var array - Storage for $data
22
- */
23
- private $data = array();
24
-
25
- /**
26
- * Storage for mapping
27
- *
28
- * @var array
29
- */
30
- private $mapping = array(
31
- 'x' => array(),
32
- 'hover' => array(),
33
- );
34
-
35
- /**
36
- * Construct will set all values and generate the date for response
37
- */
38
- public function __construct() {
39
- parent::__construct();
40
-
41
- $this->set_date_field();
42
-
43
- $this->generate();
44
- }
45
-
46
- /**
47
- * Putting $this->data and $this->mapping and give them back as a json encoded string
48
- *
49
- * @return string
50
- */
51
- public function get_json() {
52
- $return = array(
53
- 'data' => $this->data,
54
- 'mapping' => $this->mapping,
55
- );
56
-
57
- return json_encode( $return );
58
- }
59
-
60
- /**
61
- * Filtering the current data to eliminate all values which are not in given period
62
- *
63
- * @param integer $google_data
64
- *
65
- * @return integer
66
- */
67
- protected function filter_google_data( $google_data ) {
68
-
69
- foreach ( $google_data['value'] as $unix_timestamp => $value ) {
70
- if ( $this->is_date_in_period( $unix_timestamp ) ) {
71
- $return[ $unix_timestamp ] = $value;
72
- }
73
- }
74
-
75
- return $return;
76
- }
77
-
78
- /**
79
- * Which field should be taken from timestamp. Most cases J will be good
80
- */
81
- private function set_date_field() {
82
- switch ( $this->period ) {
83
- default:
84
- case 'lastweek' :
85
- case 'lastmonth' :
86
- $date_field = 'j';
87
- break;
88
- }
89
-
90
- $this->date_field = $date_field;
91
- }
92
-
93
- /**
94
- * Generate the data for the frontend based on the $google_data
95
- */
96
- private function generate() {
97
- $google_data = $this->get_google_data();
98
-
99
- foreach ( $google_data as $timestamp => $value ) {
100
- $timestamp = esc_html( $timestamp );
101
-
102
- $this->add_data( $value );
103
- $this->add_x_mapping( $timestamp );
104
- $this->add_hover_mapping( $timestamp, $value );
105
- }
106
-
107
- $this->mapping['x'] = array_filter( $this->mapping['x'] );
108
- }
109
-
110
- /**
111
- * Adding value to data property
112
- *
113
- * x is position on x-axis, always starting from 0
114
- * y is the value of that point.
115
- *
116
- * @param integer $value
117
- */
118
- private function add_data( $value ) {
119
- static $current_x = 0;
120
-
121
- $this->data[] = array(
122
- 'x' => $current_x,
123
- 'y' => $value,
124
- );
125
-
126
- $current_x ++;
127
- }
128
-
129
- /**
130
- * Add date field to the x-mapping
131
- *
132
- * Key will be auto numbered by PHP, starting with 0, the key will always point to the the x in x-axis
133
- * The value will be always the value that should be displayed.
134
- *
135
- * @param integer $timestamp
136
- */
137
- private function add_x_mapping( $timestamp ) {
138
-
139
- $is_monday = ( 'Mon' === date( 'D', $timestamp ) );
140
- $this->mapping['x'][] = ( $is_monday ) ? date( $this->date_field . ' M', $timestamp ) : null;
141
- }
142
-
143
- /**
144
- * Add date field to the hover-mapping
145
- *
146
- * @param integer $timestamp
147
- * @param integer $value
148
- */
149
- private function add_hover_mapping( $timestamp, $value ) {
150
- $this->mapping['hover'][] = esc_html( date_i18n( 'l ' . $this->date_field . ' M', $timestamp ) . ': ' . number_format_i18n( $value, 0 ) );
151
- }
152
-
153
- }
154
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-graph.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards graph inherited class.
8
- */
9
- class Yoast_GA_Dashboards_Graph extends Yoast_GA_Dashboards_Driver {
10
-
11
- /**
12
- * @var string The type of dashboard wherefore this object is created
13
- */
14
- protected $dashboard_type = 'graph';
15
-
16
- /**
17
- * @var string The hook for ajax, when this is called the hook will be executed
18
- */
19
- protected $ajax_hook = 'wp_ajax_yoast_dashboard_graphdata';
20
-
21
- /**
22
- * The object that handles the response and generates the content for dashboard
23
- *
24
- * @return Yoast_GA_Dashboards_Graph_Generate
25
- */
26
- protected function get_dashboard_generate_object() {
27
- return new Yoast_GA_Dashboards_Graph_Generate();
28
- }
29
-
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-table-generate.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards table inherited class.
8
- */
9
- class Yoast_GA_Dashboards_Table_Generate extends Yoast_GA_Dashboards_Driver_Generate {
10
-
11
- /**
12
- * @var string - The ID of requested dimension
13
- */
14
- protected $dimension_id;
15
-
16
- /**
17
- * Construct will set all values and generate the date for response
18
- */
19
- public function __construct() {
20
- parent::__construct();
21
-
22
- $this->set_dimension_id();
23
-
24
- $this->generate();
25
- }
26
-
27
- /**
28
- * Putting $this->data and $this->mapping and give them back as a json encoded string
29
- *
30
- * @return string
31
- */
32
- public function get_json() {
33
- $return = array(
34
- 'data' => $this->escape_strings_array( $this->data ),
35
- );
36
-
37
- return json_encode( $return );
38
- }
39
-
40
- /**
41
- * Filtering the current data to eliminate all values which are not in given period
42
- *
43
- * @param integer $google_data
44
- *
45
- * @return integer
46
- */
47
- protected function filter_google_data( $google_data ) {
48
- return $google_data['value'];
49
- }
50
-
51
- /**
52
- * Setting the dimension_id for current request. Based on dimension_id the graph_type will be set, this to
53
- * handle the request correctly
54
- */
55
- private function set_dimension_id() {
56
- $this->dimension_id = filter_input( INPUT_GET, 'dimension_id' );
57
-
58
- if ( ! empty( $this->dimension_id ) ) {
59
- $this->graph_type = 'ga:dimension' . $this->dimension_id;
60
- }
61
- else {
62
- $this->graph_type = $this->graph_type;
63
- }
64
- }
65
-
66
- /**
67
- * Generate the data for the frontend based on the $google_data
68
- */
69
- private function generate() {
70
- $google_data = $this->get_google_data();
71
- $this->data = is_array( $google_data ) ? array_values( $google_data ) : array();
72
- }
73
-
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/drivers/class-admin-dashboards-table.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- /**
7
- * Dashboards table inherited class.
8
- */
9
- class Yoast_GA_Dashboards_Table extends Yoast_GA_Dashboards_Driver {
10
-
11
- /**
12
- * @var string The type of dashboard wherefore this object is created
13
- */
14
- protected $dashboard_type = 'table';
15
-
16
- /**
17
- * @var string The hook for ajax, when this is called the hook will be executed
18
- */
19
- protected $ajax_hook = 'wp_ajax_yoast_dashboard_tabledata';
20
-
21
- /**
22
- * The object that handles the response and generates the content for dashboard
23
- *
24
- * @return Yoast_GA_Dashboards_Table_Generate
25
- */
26
- protected function get_dashboard_generate_object() {
27
- return new Yoast_GA_Dashboards_Table_Generate();
28
- }
29
-
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/views/graph.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- ?>
7
- <div id="graph-<?php echo $dashboard; ?>" class="yoast-dashboard yoast-graph" data-label="<?php echo $settings['title']; ?>" data-percent="<?php echo ! empty( $settings['data-percent'] ); ?>">
8
- <h3>
9
- <span class='alignleft'><?php echo $settings['title']; ?></span>
10
- <?php
11
- if ( ! empty( $settings['help'] ) ) {
12
- echo Yoast_GA_Admin_Form::show_help( 'graph-' . $dashboard, $settings['help'] );
13
- }
14
- ?>
15
- <span class='alignright period'><?php echo __( 'Last month', 'google-analytics-for-wordpress' ); ?></span>
16
- </h3>
17
-
18
- <?php
19
- if ( empty( $settings['hide_y_axis'] ) ) {
20
- echo "<div class='yoast-graph-yaxis'></div>";
21
- } ?>
22
- <div class="yoast-graph-holder"></div>
23
-
24
- <?php
25
- if ( empty( $settings['hide_x_axis'] ) ) {
26
- echo "<div class='yoast-graph-xaxis'></div>";
27
- } ?>
28
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/dashboards/views/table.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- ?>
7
- <div class='yoast-dashboard yoast-data-table' id="table-<?php echo $dashboard; ?>" data-label="<?php echo $settings['title']; ?>" data-dimension="<?php echo ( ! empty( $settings['custom-dimension-id'] ) ) ? $settings['custom-dimension-id'] : ''; ?>">
8
- <h3>
9
- <span class='alignleft'><?php echo $settings['title']; ?></span>
10
- <?php
11
- if ( ! empty( $settings['help'] ) ) {
12
- echo Yoast_GA_Admin_Form::show_help( 'graph-' . $dashboard, $settings['help'] );
13
- }
14
- ?>
15
- <span class='alignright period'><?php _e( 'Last month', 'google-analytics-for-wordpress' ); ?></span>
16
- </h3>
17
-
18
- <div>
19
- <table class="widefat fixed stripe">
20
- <thead>
21
- <th><?php echo esc_html( $settings['title'] ); ?></th>
22
- <?php foreach ( $settings['columns'] as $columns ) { ?>
23
- <th><?php echo esc_html( $columns ); ?></th>
24
- <?php } ?>
25
- </thead>
26
- </table>
27
- </div>
28
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/index.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- //Nothing to see here
3
-
4
- header( 'HTTP/1.0 403 Forbidden' );
 
 
 
 
admin/pages/dashboard.php DELETED
@@ -1,273 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- global $yoast_ga_admin;
7
-
8
- $options_class = Yoast_GA_Options::instance();
9
- $options = $options_class->get_options();
10
- $tracking_code = $options_class->get_tracking_code();
11
-
12
- echo $yoast_ga_admin->content_head();
13
- ?>
14
- <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by MonsterInsights: ', 'google-analytics-for-wordpress' ) . __( 'Dashboard', 'google-analytics-for-wordpress' ); ?> <?php do_action( 'yst_ga_dashboard_title' ); ?></h2>
15
-
16
- <h2 class="nav-tab-wrapper" id="ga-tabs">
17
- <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'Overview', 'google-analytics-for-wordpress' ); ?></a>
18
- <a class="nav-tab" id="dimensions-tab" href="#top#dimensions"><?php _e( 'Reports', 'google-analytics-for-wordpress' ); ?></a>
19
- <a class="nav-tab" id="customdimensions-tab" href="#top#customdimensions"><?php _e( 'Custom dimension reports', 'google-analytics-for-wordpress' ); ?></a>
20
- <a class="nav-tab" id="systeminfo-tab" href="#top#systeminfo"><?php _e( 'System Info', 'google-analytics-for-wordpress' ); ?></a>
21
- </h2>
22
-
23
- <script type="text/javascript">
24
- var yoast_ga_dashboard_nonce = '<?php echo wp_create_nonce( 'yoast-ga-dashboard-nonce' ); ?>';
25
-
26
- jQuery(function () {
27
- jQuery.each(
28
- jQuery('select[data-rel=toggle_dimensions]'),
29
- function (num, element) {
30
- dimension_switch(element);
31
- }
32
- );
33
- });
34
- </script>
35
-
36
- <div class="tabwrapper">
37
- <div id="general" class="wpseotab gatab active">
38
- <div class="yoast-graphs">
39
- <?php
40
- if ( $tracking_code !== '' ) {
41
- if ( empty( $options['analytics_profile'] ) ) {
42
- echo '<div class="ga-promote"><p>';
43
- echo sprintf(
44
- __( 'We need you to authenticate with Google Analytics to use this functionality. If you set your UA-code manually, this won\'t work. You can %sauthenticate your Google Analytics profile here%s to enable dashboards.', 'google-analytics-for-wordpress' ),
45
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
46
- '</a>'
47
- );
48
- echo '</p></div>';
49
- }
50
- else if ( ! Yoast_Google_Analytics::get_instance()->has_refresh_token() ) {
51
- echo '<div class="ga-promote"><p>';
52
- echo sprintf(
53
- __( 'Because we\'ve switched to a newer version of the Google Analytics API, you\'ll need to re-authenticate with Google Analytics. We\'re sorry for the inconvenience. You can %sre-authenticate your Google Analytics profile here%s.', 'google-analytics-for-wordpress' ),
54
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
55
- '</a>'
56
- );
57
- echo '</p></div>';
58
- }
59
- else {
60
- Yoast_GA_Dashboards_Display::get_instance()->display( 'general' );
61
- }
62
- }
63
- else {
64
- echo '<div class="ga-promote"><p>';
65
- echo sprintf(
66
- __( 'You have not yet finished setting up Google Analytics for Wordpress by MonsterInsights. Please %sadd your Analytics profile here%s to enable tracking.', 'google-analytics-for-wordpress' ),
67
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
68
- '</a>'
69
- );
70
- echo '</p></div>';
71
- }
72
- ?>
73
- </div>
74
- </div>
75
-
76
- <div id="dimensions" class="wpseotab gatab">
77
- <?php
78
-
79
- if ( $tracking_code !== '' ) {
80
- if ( empty( $options['analytics_profile'] ) ) {
81
- echo '<div class="ga-promote"><p>';
82
- echo sprintf(
83
- __( 'We need you to authenticate with Google Analytics to use this functionality. If you set your UA-code manually, this won\'t work. You can %sauthenticate your Google Analytics profile here%s to enable dashboards.', 'google-analytics-for-wordpress' ),
84
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
85
- '</a>'
86
- );
87
- echo '</p></div>';
88
- }
89
- else if ( ! Yoast_Google_Analytics::get_instance()->has_refresh_token() ) {
90
- echo '<div class="ga-promote"><p>';
91
- echo sprintf(
92
- __( 'Because we\'ve switched to a newer version of the Google Analytics API, you\'ll need to re-authenticate with Google Analytics. We\'re sorry for the inconvenience. You can %sre-authenticate your Google Analytics profile here%s.', 'google-analytics-for-wordpress' ),
93
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
94
- '</a>'
95
- );
96
- echo '</p></div>';
97
- }
98
- else {
99
- ?>
100
- <div class="ga-form ga-form-input">
101
- <label class="ga-form ga-form-checkbox-label ga-form-label-left"><?php echo __( 'Select a dimension', 'google-analytics-for-wordpress' ); ?></label>
102
- </div>
103
- <select data-rel='toggle_dimensions' id="toggle_dimensions" style="width: 350px"></select>
104
-
105
- <?php
106
- Yoast_GA_Dashboards_Display::get_instance()->display( 'dimensions' );
107
- }
108
- }
109
- else {
110
- echo '<div class="ga-promote"><p>';
111
- echo sprintf(
112
- __( 'You have not yet finished setting up Google Analytics for Wordpress by MonsterInsights. Please %sadd your Analytics profile here%s to enable tracking.', 'google-analytics-for-wordpress' ),
113
- '<a href=" ' . admin_url( 'admin.php?page=yst_ga_settings#top#general' ) . '">',
114
- '</a>'
115
- );
116
- echo '</p></div>';
117
- }
118
- ?>
119
- </div>
120
-
121
- <div id="customdimensions" class="wpseotab gatab">
122
- <?php
123
- do_action( 'yst_ga_custom_dimension_add-dashboards-tab' );
124
- ?>
125
- </div>
126
-
127
- <div id="systeminfo" class="wpseotab gatab">
128
- <form action="<?php echo esc_url( admin_url( 'admin.php?page=yst_ga_dashboard#top#systeminfo' ) ); ?>" method="post" dir="ltr">
129
- <textarea id="ga-debug-info" style="width: 800px; height: 400px; font-family: Menlo, Monaco, monospace; background: none; white-space: pre; overflow: auto; display: block;" class="postbox" readonly="readonly" onclick="this.focus(); this.select()" name="monsterinsights-sysinfo" title="To copy the system info, click below then press Ctrl + C (PC) or Cmd + C (Mac)."><?php
130
- global $wpdb;
131
- ob_start();
132
- print_r( $this->options );
133
- $options = ob_get_contents();
134
- ob_end_clean();
135
- // Get theme info
136
- $theme_data = wp_get_theme();
137
- $theme = $theme_data->Name . ' ' . $theme_data->Version;
138
-
139
- $return = '### Begin System Info ###' . "\n\n";
140
- // Start with the basics...
141
- $return .= '-- Site Info' . "\n\n";
142
- $return .= 'Site URL: ' . site_url() . "\n";
143
- $return .= 'Home URL: ' . home_url() . "\n";
144
- $return .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . "\n";
145
-
146
- // WordPress configuration
147
- $return .= "\n" . '-- WordPress Configuration' . "\n\n";
148
- $return .= 'Version: ' . get_bloginfo( 'version' ) . "\n";
149
- $return .= 'Language: ' . ( defined( 'WPLANG' ) && WPLANG ? WPLANG : 'en_US' ) . "\n";
150
- $return .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . "\n";
151
- $return .= 'Active Theme: ' . $theme . "\n";
152
- $return .= 'Show On Front: ' . get_option( 'show_on_front' ) . "\n";
153
- // Only show page specs if frontpage is set to 'page'
154
- if( get_option( 'show_on_front' ) == 'page' ) {
155
- $front_page_id = get_option( 'page_on_front' );
156
- $blog_page_id = get_option( 'page_for_posts' );
157
- $return .= 'Page On Front: ' . ( $front_page_id != 0 ? get_the_title( $front_page_id ) . ' (#' . $front_page_id . ')' : 'Unset' ) . "\n";
158
- $return .= 'Page For Posts: ' . ( $blog_page_id != 0 ? get_the_title( $blog_page_id ) . ' (#' . $blog_page_id . ')' : 'Unset' ) . "\n";
159
- }
160
- $return .= 'ABSPATH: ' . ABSPATH . "\n";
161
- // Make sure wp_remote_post() is working
162
- $request['cmd'] = '_notify-validate';
163
- $params = array(
164
- 'sslverify' => false,
165
- 'timeout' => 60,
166
- 'user-agent' => 'MI/' . GAWP_VERSION,
167
- 'body' => $request
168
- );
169
- $response = wp_remote_post( 'https://www.paypal.com/cgi-bin/webscr', $params );
170
- if( !is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) {
171
- $WP_REMOTE_POST = 'wp_remote_post() works';
172
- } else {
173
- $WP_REMOTE_POST = 'wp_remote_post() does not work';
174
- }
175
- $return .= 'Remote Post: ' . $WP_REMOTE_POST . "\n";
176
- $return .= 'Table Prefix: ' . 'Length: ' . strlen( $wpdb->prefix ) . ' Status: ' . ( strlen( $wpdb->prefix ) > 16 ? 'ERROR: Too long' : 'Acceptable' ) . "\n";
177
-
178
- $return .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ) . "\n";
179
- $return .= 'Memory Limit: ' . WP_MEMORY_LIMIT . "\n";
180
-
181
- $return .= "\n" . '-- MI Version' . "\n";
182
- $return .= GAWP_VERSION;
183
-
184
- // MI configuration
185
- $return .= "\n\n" . '-- MI Configuration' . "\n";
186
- $return .= $options;
187
-
188
-
189
- // Get plugins that have an update
190
- $updates = get_plugin_updates();
191
- // Must-use plugins
192
- // NOTE: MU plugins can't show updates!
193
- $muplugins = get_mu_plugins();
194
- if( count( $muplugins > 0 ) ) {
195
- $return .= "\n" . '-- Must-Use Plugins' . "\n\n";
196
- foreach( $muplugins as $plugin => $plugin_data ) {
197
- $return .= $plugin_data['Name'] . ': ' . $plugin_data['Version'] . "\n";
198
- }
199
-
200
- }
201
- // WordPress active plugins
202
- $return .= "\n" . '-- WordPress Active Plugins' . "\n\n";
203
- $plugins = get_plugins();
204
- $active_plugins = get_option( 'active_plugins', array() );
205
- foreach( $plugins as $plugin_path => $plugin ) {
206
- if( !in_array( $plugin_path, $active_plugins ) )
207
- continue;
208
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
209
- $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
210
- }
211
-
212
- // WordPress inactive plugins
213
- $return .= "\n" . '-- WordPress Inactive Plugins' . "\n\n";
214
- foreach( $plugins as $plugin_path => $plugin ) {
215
- if( in_array( $plugin_path, $active_plugins ) )
216
- continue;
217
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
218
- $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
219
- }
220
-
221
- if( is_multisite() ) {
222
- // WordPress Multisite active plugins
223
- $return .= "\n" . '-- Network Active Plugins' . "\n\n";
224
- $plugins = wp_get_active_network_plugins();
225
- $active_plugins = get_site_option( 'active_sitewide_plugins', array() );
226
- foreach( $plugins as $plugin_path ) {
227
- $plugin_base = plugin_basename( $plugin_path );
228
- if( !array_key_exists( $plugin_base, $active_plugins ) )
229
- continue;
230
- $update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
231
- $plugin = get_plugin_data( $plugin_path );
232
- $return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
233
- }
234
- }
235
- // Server configuration (really just versioning)
236
- $return .= "\n" . '-- Webserver Configuration' . "\n\n";
237
- $return .= 'PHP Version: ' . PHP_VERSION . "\n";
238
- $return .= 'MySQL Version: ' . $wpdb->db_version() . "\n";
239
- $return .= 'Webserver Info: ' . $_SERVER['SERVER_SOFTWARE'] . "\n";
240
-
241
- // PHP configs... now we're getting to the important stuff
242
- $return .= "\n" . '-- PHP Configuration' . "\n\n";
243
- $return .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . "\n";
244
- $return .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . "\n";
245
- $return .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . "\n";
246
- $return .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . "\n";
247
- $return .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . "\n";
248
- $return .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . "\n";
249
- $return .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . "\n";
250
-
251
- // PHP extensions and such
252
- $return .= "\n" . '-- PHP Extensions' . "\n\n";
253
- $return .= 'cURL: ' . ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ) . "\n";
254
- $return .= 'fsockopen: ' . ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ) . "\n";
255
- $return .= 'SOAP Client: ' . ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ) . "\n";
256
- $return .= 'Suhosin: ' . ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ) . "\n";
257
-
258
- $return .= "\n" . '### End System Info ###';
259
- echo $return;
260
- ?>
261
- </textarea>
262
- <p class="submit">
263
- <input type="hidden" name="monsterinsights-action" value="download_sysinfo" />
264
- <?php submit_button( 'Download System Info File', 'primary', 'monsterinsights-download-sysinfo', false ); ?>
265
- </p>
266
- </form>
267
- </div>
268
- </div>
269
-
270
-
271
- <?php
272
- echo $yoast_ga_admin->content_footer();
273
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/extensions.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- global $yoast_ga_admin;
7
-
8
- echo $yoast_ga_admin->content_head();
9
-
10
- $has_extensions = false;
11
-
12
- $extensions = $yoast_ga_admin->get_extensions();
13
- ?>
14
- <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by MonsterInsights: ', 'google-analytics-for-wordpress' ) . __( 'Extensions', 'google-analytics-for-wordpress' ); ?></h2>
15
-
16
- <h2 class="nav-tab-wrapper" id="ga-tabs">
17
- <a class="nav-tab active" id="extensions-tab" href="#top#extensions"><?php _e( 'Extensions', 'google-analytics-for-wordpress' ); ?></a>
18
- <a class="nav-tab" id="licenses-tab" href="#top#licenses"><?php _e( 'Licenses', 'google-analytics-for-wordpress' ); ?></a>
19
- </h2>
20
- <div class="tabwrapper">
21
- <div id="extensions" class="wpseotab gatab">
22
- <?php
23
- foreach ( $extensions as $name => $extension ) :
24
- if ( 'uninstalled' !== $extension->status ) {
25
- $has_extensions = true;
26
- }
27
- ?>
28
- <div class="extension <?php echo $name; ?>">
29
- <a target="_blank" href="<?php echo $extension->url; ?>#utm_medium=banner&utm_source=gawp-config&utm_campaign=extension-page-banners">
30
- <h3><?php echo $extension->title; ?></h3>
31
- </a>
32
-
33
- <p><?php echo $extension->desc; ?></p>
34
- <p>
35
- <?php if ( 'uninstalled' == $extension->status ) : ?>
36
- <a target="_blank" href="<?php echo $extension->url; ?>#utm_medium=banner&utm_source=gawp-config&utm_campaign=extension-page-banners" class="button-primary"><?php echo __( 'Get this extension', 'google-analytics-for-wordpress' ); ?></a>
37
- <?php else : ?>
38
- <?php if ( 'inactive' == $extension->status ) : ?>
39
- <a href="#top#licenses" class="activate-link button-primary"><?php echo __( 'Activate License', 'google-analytics-for-wordpress' ); ?></a>
40
- <?php else : ?>
41
- <button class="button-primary installed"><?php echo __( 'Installed', 'google-analytics-for-wordpress' ); ?></button>
42
- <?php endif; ?>
43
- <?php endif; ?>
44
- </p>
45
- </div>
46
- <?php endforeach; ?>
47
- </div>
48
- <div id="licenses" class="wpseotab gatab">
49
- <?php
50
- if ( ! $has_extensions ) {
51
- echo '<p>' . __( 'You have not installed any extensions for Google Analytics by MonsterInsights, so there are no licenses to activate.', 'google-analytics-for-wordpress' ) . '</p>';
52
- }
53
- else {
54
- do_action( 'yst_ga_show_license_form' );
55
- }
56
- ?>
57
- </div>
58
- </div>
59
- <div class="clear"></div>
60
-
61
- <?php
62
- echo $yoast_ga_admin->content_footer();
63
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/settings.php DELETED
@@ -1,188 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- global $yoast_ga_admin;
7
-
8
- echo $yoast_ga_admin->content_head();
9
- ?>
10
- <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by MonsterInsights: ', 'google-analytics-for-wordpress' ) . __( 'Settings', 'google-analytics-for-wordpress' ); ?></h2>
11
-
12
- <?php
13
- settings_errors( 'yoast_google_analytics' );
14
- ?>
15
-
16
- <h2 class="nav-tab-wrapper" id="ga-tabs">
17
- <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'google-analytics-for-wordpress' ); ?></a>
18
- <a class="nav-tab" id="universal-tab" href="#top#universal"><?php _e( 'Universal', 'google-analytics-for-wordpress' ); ?></a>
19
- <a class="nav-tab" id="advanced-tab" href="#top#advanced"><?php _e( 'Advanced', 'google-analytics-for-wordpress' ); ?></a>
20
- <a class="nav-tab" id="customdimensions-tab" href="#top#customdimensions"><?php _e( 'Custom Dimensions', 'google-analytics-for-wordpress' ); ?></a>
21
- <?php do_action( 'yst_ga_custom_tabs-tab' ); ?>
22
- <a class="nav-tab" id="debugmode-tab" href="#top#debugmode"><?php _e( 'Debug mode', 'google-analytics-for-wordpress' ); ?></a>
23
- </h2>
24
-
25
- <?php
26
- echo Yoast_GA_Admin_Form::create_form( 'settings' );
27
- ?>
28
- <input type="hidden" name="return_tab" id="return_tab" value="general" />
29
- <div class="tabwrapper">
30
- <div id="general" class="gatab">
31
- <?php
32
- echo '<h2>' . __( 'General settings', 'google-analytics-for-wordpress' ) . '</h2>';
33
-
34
- echo '<div id="ga-promote">';
35
-
36
- $ga_class = Yoast_Google_Analytics::get_instance();
37
- $wp_block_google = $ga_class->check_google_access_from_wp();
38
- $check_google_access = $ga_class->check_google_access();
39
-
40
- if ( $wp_block_google && $check_google_access ) {
41
-
42
- $profiles = Yoast_GA_Admin_Form::parse_optgroups( $yoast_ga_admin->get_profiles() );
43
-
44
- $auth_url = Yoast_Google_Analytics::get_instance()->create_auth_url();
45
- add_thickbox();
46
- echo '<script>yst_thickbox_heading = "' . __( 'Paste your Google authentication code', 'google-analytics-for-wordpress' ) . '";</script>';
47
-
48
- echo "<div id='google_ua_code_field'>";
49
- if ( count( $profiles ) == 0 ) {
50
- echo '<div class="ga-form ga-form-input">';
51
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">' . __( 'Google profile', 'google-analytics-for-wordpress' ) . ':</label>';
52
- echo '<a id="yst_ga_authenticate" class="button" onclick="yst_popupwindow(\'' . $auth_url . '\',500,500);">' . __( 'Authenticate with your Google account', 'google-analytics-for-wordpress' ) . '</a>';
53
- echo '</div>';
54
- echo '<div class="ga-form ga-form-input">';
55
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">' . __( 'Current UA-profile', 'google-analytics-for-wordpress' ) . '</label>';
56
- echo esc_html( $yoast_ga_admin->get_tracking_code() );
57
- echo '</div>';
58
- }
59
- else {
60
- echo Yoast_GA_Admin_Form::select( __( 'Analytics profile', 'google-analytics-for-wordpress' ), 'analytics_profile', $profiles, null, false, __( 'Select a profile', 'google-analytics-for-wordpress' ) );
61
-
62
- echo '<div class="ga-form ga-form-input">';
63
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">&nbsp;</label>';
64
- echo '<a id="yst_ga_authenticate" class="button" onclick="yst_popupwindow(\'' . $auth_url . '\',500,500);">' . __( 'Re-authenticate with your Google account', 'google-analytics-for-wordpress' ) . '</a>';
65
- echo '</div>';
66
- }
67
- echo '</div>';
68
-
69
- echo '<div id="oauth_code" class="ga-form ga-form-input">';
70
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">' . __( 'Paste your Google code here', 'google-analytics-for-wordpress' ) . ':</label>';
71
- echo Yoast_GA_Admin_Form::input( 'text', null, 'google_auth_code', null, null );
72
-
73
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle-submit">&nbsp;</label>';
74
- echo '<div class="ga-form ga-form-input"><input type="submit" name="ga-form-settings" value="' . __( 'Save authentication code', 'google-analytics-for-wordpress' ) . '" class="button button-primary ga-form-submit" id="yoast-ga-form-submit-settings" onclick="yst_closepopupwindow();"></div>';
75
- echo '</div>';
76
- }
77
- else {
78
- echo '<h3>' . __( 'Cannot connect to Google', 'google-analytics-for-wordpress' ) . '</h3>';
79
- if ( $wp_block_google == false && $check_google_access == false ) {
80
- echo '<p>' . __( 'Your server is blocking requests to Google, to fix this, add <code>*.googleapis.com</code> to the <code>WP_ACCESSIBLE_HOSTS</code> constant in your <em>wp-config.php</em> or ask your webhost to do this.', 'google-analytics-for-wordpress' ) . '</p>';
81
- }
82
- else {
83
- echo '<p>' . __( 'Your firewall or webhost is blocking requests to Google, please ask your webhost company to fix this.', 'google-analytics-for-wordpress' ) . '</p>';
84
- }
85
- echo '<p>' . __( 'Until this is fixed, you can only use the manual authentication method and cannot use the dashboards feature.', 'google-analytics-for-wordpress' ) . '</p>';
86
- }
87
-
88
- echo '<label class="ga-form ga-form-checkbox-label ga-form-label-left">';
89
- echo Yoast_GA_Admin_Form::input( 'checkbox', null, 'manual_ua_code', __( 'Manually enter your UA code', 'google-analytics-for-wordpress' ) );
90
- echo '</label>';
91
- echo '<div id="enter_ua">';
92
- echo Yoast_GA_Admin_Form::input( 'text', null, 'manual_ua_code_field' );
93
- echo '<p><strong>' . __( 'Warning: If you use a manual UA code, you won\'t be able to use the dashboards.', 'google-analytics-for-wordpress' ) . '</strong></p>';
94
- echo '</div>';
95
- echo '<div class="clear"></div></div>';
96
- ?>
97
- <div class="clear"><br /></div>
98
- <?php
99
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Track outbound click and downloads', 'google-analytics-for-wordpress' ), 'track_outbound', null, __( 'Clicks and downloads will be tracked as events, you can find these under Content &#xBB; Event Tracking in your Google Analytics reports.', 'google-analytics-for-wordpress' ) );
100
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow tracking of anonymous data', 'google-analytics-for-wordpress' ), 'anonymous_data', null, __( 'By allowing us to track anonymous data we can better help you, because we know with which WordPress configurations, themes and plugins we should test. No personal data will be submitted.', 'google-analytics-for-wordpress' ) );
101
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Anonymize IPs', 'google-analytics-for-wordpress' ), 'anonymize_ips', null, sprintf( __( 'This adds %1$s, telling Google Analytics to anonymize the information sent by the tracker objects by removing the last octet of the IP address prior to its storage.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApi_gat?csw=1#_gat._anonymizeIp" target="_blank"><code>_anonymizeIp</code></a>' ) );
102
- echo Yoast_GA_Admin_Form::select( __( 'Ignore users', 'google-analytics-for-wordpress' ), 'ignore_users', $yoast_ga_admin->get_userroles(), __( 'Users of the role you select will be ignored, so if you select Editor, all Editors will be ignored.', 'google-analytics-for-wordpress' ), true );
103
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Disable analytics dashboard', 'google-analytics-for-wordpress' ), 'dashboards_disabled', null, __( 'This will completely disable the dashboard and stop the plugin from fetching the latest analytics data.', 'google-analytics-for-wordpress' ) );
104
-
105
- ?>
106
- </div>
107
- <div id="universal" class="gatab">
108
- <?php
109
- echo '<h2>' . __( 'Universal settings', 'google-analytics-for-wordpress' ) . '</h2>';
110
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable Universal tracking', 'google-analytics-for-wordpress' ), 'enable_universal', null, sprintf( __( 'First enable Universal tracking in your Google Analytics account. Please read %1$sthis guide%2$s to learn how to do that.', 'google-analytics-for-wordpress' ), '<a href="https://www.monsterinsights.com/docs/enable-demographics-and-interests-report-in-google-analytics/#utm_medium=kb-link&utm_source=gawp-config&utm_campaign=wpgaplugin" target="_blank">', '</a>' ) );
111
- echo Yoast_GA_Admin_Form::input(
112
- 'checkbox',
113
- __( 'Enable Demographics and Interests Reports for Remarketing and Advertising', 'google-analytics-for-wordpress' ),
114
- 'demographics',
115
- '<span id="yoast-ga-displayfeatures-warning">' . __( 'Note that usage of this function is affected by privacy and cookie laws around the world. Be sure to follow the laws that affect your target audience.', 'google-analytics-for-wordpress' ) . '</span>',
116
- /* Transators: %1$s contains the link to a knowledge base article, %2$s contains the the closing tag for both links, %3$s contains a link to Google documentation about remarketing. */
117
- sprintf(
118
- __( 'Check this setting to add the Demographics and Remarketing features to your Google Analytics tracking code. We\'ve written an article in our %1$sknowledge base%2$s about Demographics and Interest reports. For more information about Remarketing, we refer you to %3$sGoogle\'s documentation%2$s.', 'google-analytics-for-wordpress' ),
119
- '<a href="https://www.monsterinsights.com/docs/enable-demographics-and-interests-report-in-google-analytics/#utm_medium=kb-link&amp;utm_source=gawp-config&amp;utm_campaign=wpgaplugin" target="_blank">',
120
- '</a>',
121
- '<a href="https://support.google.com/analytics/answer/2444872?hl=' . get_locale() . '" target="_blank">'
122
- )
123
- );
124
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enhanced Link Attribution', 'google-analytics-for-wordpress' ), 'enhanced_link_attribution', null, sprintf( __( 'Add %1$sEnhanced Link Attribution%2$s to your tracking code.', 'google-analytics-for-wordpress' ), '<a href="https://support.google.com/analytics/answer/2558867" target="_blank">', ' </a>' ) );
125
-
126
- /**
127
- * Action: 'yst_ga_universal_tab' - Allow adding to the universal tab of the settings
128
- */
129
- do_action( 'yst_ga_universal_tab' );
130
- ?>
131
- </div>
132
- <div id="advanced" class="gatab">
133
- <?php
134
- echo '<h2>' . __( 'Advanced settings', 'google-analytics-for-wordpress' ) . '</h2>';
135
- echo Yoast_GA_Admin_Form::select( __( 'Track downloads as', 'google-analytics-for-wordpress' ), 'track_download_as', $yoast_ga_admin->track_download_types(), __( 'Not recommended, as this would skew your statistics, but it does make it possible to track downloads as goals.', 'google-analytics-for-wordpress' ) );
136
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Extensions of files to track as downloads', 'google-analytics-for-wordpress' ), 'extensions_of_files', null, 'Please separate extensions using commas' );
137
- echo Yoast_GA_Admin_Form::select( __( 'Track full URL of outbound clicks or just the domain', 'google-analytics-for-wordpress' ), 'track_full_url', $yoast_ga_admin->get_track_full_url() );
138
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Subdomain tracking', 'google-analytics-for-wordpress' ), 'subdomain_tracking', null, sprintf( __( 'This allows you to set the domain that\'s set by %1$s for tracking subdomains.<br/>If empty, this will not be set.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiDomainDirectory#_gat.GA_Tracker_._setDomainName" target="_blank"><code>_setDomainName</code></a>' ) );
139
-
140
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Set path for internal links to track as outbound links', 'google-analytics-for-wordpress' ), 'track_internal_as_outbound', null, sprintf( __( 'If you want to track all internal links that begin with %1$s, enter %1$s in the box above. If you have multiple prefixes you can separate them with comma\'s: %2$s', 'google-analytics-for-wordpress' ), '<code>/out/</code>', '<code>/out/,/recommends/</code>' ) );
141
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Label for those links', 'google-analytics-for-wordpress' ), 'track_internal_as_label', null, 'The label to use for these links, this will be added to where the click came from, so if the label is "aff", the label for a click from the content of an article becomes "outbound-article-aff".' );
142
-
143
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Tag links in RSS feed with campaign variables', 'google-analytics-for-wordpress' ), 'tag_links_in_rss', null, __( 'Do not use this feature if you use FeedBurner, as FeedBurner can do this automatically and better than this plugin can. Check <a href="https://support.google.com/feedburner/answer/165769?hl=en&amp;ref_topic=13075" target="_blank">this help page</a> for info on how to enable this feature in FeedBurner.', 'google-analytics-for-wordpress' ) );
144
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow anchor', 'google-analytics-for-wordpress' ), 'allow_anchor', null, sprintf( __( 'This adds a %1$s call to your tracking code, and makes RSS link tagging use a %2$s as well.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiCampaignTracking?csw=1#_gat.GA_Tracker_._setAllowAnchor" target="_blank"><code>_setAllowAnchor</code></a>', '<code>#</code>' ) );
145
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Add <code>_setAllowLinker</code>', 'google-analytics-for-wordpress' ), 'add_allow_linker', null, sprintf( __( 'This adds a %1$s call to your tracking code, allowing you to use %2$s and related functions.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiDomainDirectory?csw=1#_gat.GA_Tracker_._setAllowLinker" target="_blank"><code>_setAllowLinker</code></a>', ' <code>_link</code>' ) );
146
- if ( current_user_can( 'unfiltered_html' ) ) {
147
- echo Yoast_GA_Admin_Form::textarea( __( 'Custom code', 'google-analytics-for-wordpress' ), 'custom_code', sprintf( __( 'Not for the average user: this allows you to add a line of code, to be added before the %1$s call.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiBasicConfiguration#_gat.GA_Tracker_._trackPageview" target="_blank"><code>_trackPageview</code></a>' ) );
148
- }
149
-
150
- /**
151
- * Action: 'yst_ga_advanced-tab' - Allow adding to the advanced tab of the settings
152
- */
153
- do_action( 'yst_ga_advanced-tab' );
154
- ?>
155
- </div>
156
- <div id="customdimensions" class="gatab">
157
- <?php
158
- echo '<h2>' . __( 'Custom dimensions', 'google-analytics-for-wordpress' ) . '</h2>';
159
- do_action( 'yst_ga_custom_dimensions_tab-content' );
160
- ?>
161
- </div>
162
- <?php do_action( 'yst_ga_custom_tabs-content' ); ?>
163
- <div id="debugmode" class="gatab">
164
- <?php
165
- echo '<h2>' . __( 'Debug', 'google-analytics-for-wordpress' ) . '</h2>';
166
-
167
- echo '<div id="ga-promote">';
168
- echo '<p class="ga-topdescription">' . __( 'If you want to confirm that tracking on your blog is working as it should, enable this option and check the console of your browser. Be absolutely sure to disable debugging afterwards, as it is slower than normal tracking.', 'google-analytics-for-wordpress' ) . '</p>';
169
- echo '<p class="ga-topdescription">' . __( '<strong>Note</strong> the debugging is only loaded for administrators.', 'google-analytics-for-wordpress' ) . '</p>';
170
- echo '</div>';
171
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable debug mode', 'google-analytics-for-wordpress' ), 'debug_mode' );
172
- ?>
173
- </div>
174
- </div>
175
- <?php
176
- echo Yoast_GA_Admin_Form::end_form( __( 'Save changes', 'google-analytics-for-wordpress' ), 'settings', 'yst_closepopupwindow();' );
177
- echo $yoast_ga_admin->content_footer();
178
- ?>
179
- <script type="text/javascript">
180
- jQuery(document).ready(
181
- function () {
182
- jQuery('#yoast-ga-form-select-settings-analytics_profile').chosen({
183
- group_search: true
184
- });
185
- jQuery('#yoast-ga-form-select-settings-ignore_users').chosen({placeholder_text_multiple: '<?php echo __( 'Select the users to ignore', 'google-analytics-for-wordpress' ); ?>'});
186
- }
187
- );
188
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/views/content-footer.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
- /**
3
- * @package GoogleAnalytics\Admin
4
- */
5
-
6
- ?>
7
- </div>
8
- <div class="yoast-ga-banners">
9
- <?php foreach ( $banners as $item ) : ?>
10
- <p><a href="<?php echo $item['url']; ?>" target="_blank">
11
- <img src="<?php echo $item['banner']; ?>" alt="<?php echo $item['title']; ?>" class="yoast-banner" border="0" width="250" />
12
- </a></p>
13
- <?php endforeach; ?>
14
- <?php _e( 'Remove these ads?', 'google-analytics-for-wordpress' ); ?><br />
15
- <a href="https://www.monsterinsights.com/pricing/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin" target="_blank"><?php _e( 'Upgrade to Google Analytics By MonsterInsights Pro »', 'google-analytics-for-wordpress' ); ?></a>
16
- </div>
17
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/views/content_head.php DELETED
@@ -1,2 +0,0 @@
1
- <div id="yoast-ga-wrapper">
2
- <div class="yoast-ga-content">
 
 
assets/css/admin.css ADDED
@@ -0,0 +1,540 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Developer's Notice:
3
+ *
4
+ * Note: CSS in this file (and this file itself) is not guaranteed backwards compatibility. Rules can be added, changed or removed at any time without notice.
5
+ * For more information see the `Backwards Compatibility Guidelines for Developers` section of the README.md file.
6
+ **/
7
+ /** Generic MonsterInsights Styles **/
8
+ /** Hide other plugin's error messages on our pages */
9
+ body.monsterinsights_page div.wrap > div.error,body.monsterinsights_page div.wrap > div.notice,body.monsterinsights_page div.wrap > div.updated{margin-left:20px;margin-right:20px}
10
+ body.monsterinsights_page .update-nag{margin-left:20px;margin-bottom:20px}
11
+
12
+ /** Sizes/Layout **/
13
+ body.monsterinsights_page #wpcontent{padding-left:0}
14
+ body.monsterinsights_page div.wrap{margin:0 20px}
15
+ body.monsterinsights_page #wpbody,body.monsterinsights_page #wpfooter,body.monsterinsights_page, body.monsterinsights_page #wpwrap{background-color:#fff}
16
+ @media (max-width: 599px) {
17
+ body.monsterinsights_page #wpbody {padding-top: 0;}
18
+ }
19
+
20
+ .monsterinsights-grid{margin:0 0 50px}
21
+ .monsterinsights-grid:after{content:"";display:table;clear:both}
22
+ .monsterinsights-col-1-1{width:100%}
23
+ .monsterinsights-col-7-8{width:87.5%}
24
+ .monsterinsights-col-3-4{width:75%}
25
+ .monsterinsights-col-2-3{width:66.66%}
26
+ .monsterinsights-col-1-2{width:50%}
27
+ .monsterinsights-col-1-3{width:33.33%}
28
+ .monsterinsights-col-1-4{width:25%}
29
+ .monsterinsights-col-1-8{width:12.5%}
30
+ [class*="monsterinsights-col-"]{float:left;padding-right:20px;box-sizing:border-box}
31
+ .monsterinsights-grid [class*="monsterinsights-col-"]:last-of-type{padding-right:0}
32
+
33
+ /** Special Classes */
34
+ .monsterinsights-hideme{display:none;visibility: hidden;}
35
+ .monsterinsights-no-text-decoration{text-decoration:none}
36
+
37
+ /** Clearfixes */
38
+ .monsterinsights-clear{clear:both}
39
+ .monsterinsights-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}
40
+ .monsterinsights-clearfix{content:"";display:table;clear:both}
41
+ .monsterinsights-clearfix-after:after{content:"";display:table;clear:both}
42
+
43
+ /* Tooltips */
44
+ .monsterinsights-help-tip{cursor:help}
45
+ .monsterinsights-ui-tooltip{background:#333!important;border-width:1px!important;border-radius:3px!important;box-shadow:1px 1px 2px 1px rgba(214,214,214,0.5)!important;color:#dedede!important;max-width:300px!important;padding:7px!important;text-rendering:optimizeLegibility;text-shadow:none!important;z-index:9999!important}
46
+
47
+ /** Buttons */
48
+ body.monsterinsights_page .button{-webkit-border-radius:2px;-moz-border-radius:2px;-o-border-radius:2px;border-radius:2px;padding:0 16px 1px;height:33px;line-height:30px;text-decoration:none;text-shadow:none;font-weight:600;-webkit-box-shadow:none;box-shadow:none}
49
+ body.monsterinsights_page .button.button-small{padding:0 8px 1px;line-height:22px;height:24px}
50
+ body.monsterinsights_page .button.button-x-large{padding:0 32px 1px;line-height:48px;height:50px;font-size:18px;text-transform:uppercase}
51
+ body.monsterinsights_page .button.show-settings{height:auto}
52
+ body.monsterinsights_page .button.button-primary{background:#47c1a5;border-color:#3ca489;-webkit-box-shadow:none;box-shadow:none;color:#fff;border:1px solid #3ca489;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#47c1a5}
53
+ body.monsterinsights_page .button.button-primary:hover{background:#3ba389;border-color:#3ba389;color:#fff}
54
+ body.monsterinsights_page .button.button-action{background:#479be7;border-color:#4182bf;-webkit-box-shadow:none;box-shadow:none;color:#fff;border:1px solid #4182bf;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#479be7}
55
+ body.monsterinsights_page .button.button-action:hover{background:#4183bf;border-color:#4183bf;color:#fff}
56
+ body.monsterinsights_page .button.button-danger{background:#fff;border-color:#e3e9ed;-webkit-box-shadow:none;box-shadow:none;color:#000;border:1px solid #e3e9ed;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff}
57
+ body.monsterinsights_page .button.button-danger:hover{background:#e3e9ed;border-color:#e3e9ed;color:#000}
58
+ @media (min-width: 600px) and (max-width: 767px) {
59
+ body.monsterinsights_page .button{margin-top:10px}
60
+ }
61
+
62
+ /** Clipboard & Code */
63
+ div.monsterinsights-code{position:relative;margin:0 0 10px}
64
+ div.monsterinsights-code:after{content:"";display:table;clear:both}
65
+ div.monsterinsights-code code{display:block;font-size:11px;padding:5px 20px 5px 5px}
66
+ a.monsterinsights-clipboard{position:absolute;top:5px;right:5px;color:#23282d;width:33px;padding:0}
67
+ a.monsterinsights-clipboard span{display:block;text-indent:-9999px}
68
+
69
+ /* Page Header */
70
+ /* Banner + Background */
71
+ #monsterinsights-header-temp{position:relative;margin:0}
72
+ #monsterinsights-header{background-color:#f3f5ff;background-image:url(images/waves.png);background-repeat:no-repeat;margin:0;height:119px}
73
+ @media only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 21),only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min-device-pixel-ratio: 2) {
74
+ #monsterinsights-header{background-image:url(images/waves@x2.png);background-size:1356px 119px}
75
+ }
76
+
77
+ /* Title + Mascot */
78
+ .monsterinsights-header-title{padding-top:50px;padding-left:20px;margin:0}
79
+ .monsterinsights-header-mascot{float:right;position:absolute;top:0;right:0;margin-top:10px;margin-right:20px;z-index:100}
80
+
81
+ /* Media Queries */
82
+ @media (max-width: 610px) {
83
+ .monsterinsights-header-mascot{display:none}
84
+ .monsterinsights-header-title{padding-top:70px}
85
+ #monsterinsights-addon-heading form{margin-right:0}
86
+ }
87
+
88
+ /* Messages */
89
+ /* Generic */
90
+ .monsterinsights-notice{border:1px solid;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;box-sizing:border-box;display:table; width: 100%; margin: 10px 0px;}
91
+ .monsterinsights-notice:after{content:"";display:table;clear:both}
92
+ .monsterinsights-notice-icon{padding:20px;box-sizing:border-box;width:60px;color:#fff;font-family:"FontAwesome";font-size:18px;-moz-border-radius:5px 0 0;-webkit-border-radius:5px 0 0;border-radius:5px 0 0;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;display:table-cell;vertical-align: middle;text-align: center;}
93
+ .monsterinsights-notice-text{color:#434751;font-size:16px;font-weight:700;padding: 0px 60px 0px 20px;box-sizing:border-box;word-wrap:break-word;display:table-cell;position: relative;vertical-align: middle;}
94
+ body.monsterinsights_page div.wrap > div.error,body.monsterinsights_page div.wrap > div.notice,body.monsterinsights_page div.wrap > div.updated{margin-left:0;margin-right:0}
95
+ .monsterinsights-notice .button { margin: 0px 0px 1em 0px }
96
+
97
+ /* Alert */
98
+ .monsterinsights-alert-notice-icon{background-color:#fdbf2f}
99
+ .monsterinsights-alert-notice{border-color:#fdbf2f;background-color:rgba(253,192,47,0.1)}
100
+
101
+ /* Error */
102
+ .monsterinsights-error-notice-icon{background-color:#df4228}
103
+ .monsterinsights-error-notice{border-color:#df4228;background-color:rgba(224,66,40,0.1)}
104
+
105
+ /* Info */
106
+ .monsterinsights-info-notice-icon{background-color:#479be7}
107
+ .monsterinsights-info-notice{border-color:#479be7;background-color:rgba(72,155,232,0.1)}
108
+
109
+ /* Success */
110
+ .monsterinsights-success-notice-icon{background-color:#47c1a5}
111
+ .monsterinsights-success-notice{border-color:#47c1a5;background-color:rgba(71,194,165,0.1)}
112
+
113
+ /* Dismiss Notice */
114
+ .monsterinsights-notice p.monsterinsights-intro{border:none!important;margin:0 0 20px!important;padding:0!important}
115
+ .monsterinsights-notice .notice-dismiss{top:10px;right:10px;color:#000}
116
+ .monsterinsights-notice .notice-dismiss:before{color:#000;width:26px;height:26px;font-size:22px}
117
+
118
+ /** Other */
119
+
120
+
121
+ /** MonsterInsights Icons **/
122
+ /** Generic Icons Styles **/
123
+ @font-face{font-family:'MISettings';src:url(../fonts/MISettings.eot);src:url(../fonts/MISettings.eot?#iefix) format("embedded-opentype"),url(../fonts/MISettings.woff) format("woff"),url(../fonts/MISettings.ttf) format("truetype"),url(../fonts/MISettings.svg#MISettings) format("svg");font-weight:400;font-style:normal}
124
+ [class*='monstericon-']:before{display:inline-block;font-family:'MISettings';font-style:normal;font-weight:400;line-height:50px;padding-right:7px;padding-left:5px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:middle}
125
+ [class*='monstericon-'].monsterinsights-active:before{color:#479be7}
126
+ [class*='monstericon-']:active:before{color:#479be7}
127
+ [class*='monstericon-']:hover:before{color:#479be7}
128
+
129
+ /** Defined Icons **/
130
+ .monstericon-ads:before{content:'\0041'}
131
+ .monstericon-affiliates:before{content:'\0042'}
132
+ .monstericon-compatibility:before{content:'\0043'}
133
+ .monstericon-demographics:before{content:'\0044'}
134
+ .monstericon-dimensions:before{content:'\0045'}
135
+ .monstericon-files:before{content:'\0046'}
136
+ .monstericon-ecommerce:before{content:'\0047'}
137
+ .monstericon-engagement:before{content:'\0048'}
138
+ .monstericon-forms:before{content:'\0049'}
139
+ .monstericon-links:before{content:'\004a'}
140
+ .monstericon-memberships:before{content:'\004b'}
141
+ .monstericon-notifications:before{content:'\004c'}
142
+ .monstericon-performance:before{content:'\004d'}
143
+ .monstericon-permissions:before{content:'\004e'}
144
+ .monstericon-reporting:before{content:'\004f'}
145
+ .monstericon-social:before{content:'\0050'}
146
+ .monstericon-media:before{content:'\0051'}
147
+ .monsterinsights-upgrade-menu-icon{float:right;color:#7f8591;font-size:10px;font-weight:700;text-transform:uppercase;line-height:1;display:inline-block;padding:6px 12px;background-color:#fff;border-radius:3px;margin-right:18px;margin-top:15px}
148
+ .monsterinsights-main-nav-item.monsterinsights-active .monsterinsights-upgrade-menu-icon,.monsterinsights-main-nav-item:hover .monsterinsights-upgrade-menu-icon{background-color:#f7f8fa}
149
+
150
+ /* Icon Media Queries **/
151
+ @media only screen and (max-width: 767px) {
152
+ [class*='monstericon-']:before{ display: none !important;content: '';}
153
+ span.monsterinsights-upgrade-menu-icon{display:none}
154
+ }
155
+
156
+ /** Navigation Styles **/
157
+ /** Nav Container **/
158
+ /** Generic **/
159
+ .monsterinsights-nav-container{border:0;background-color:#615d9b;margin:0;display:table;width:100%}
160
+ h1.monsterinsights-nav-container { padding: 0px;}
161
+
162
+ /** Main Nav Container **/
163
+ .monsterinsights-main-nav-container{ height:50px;}
164
+
165
+ /** Sub Nav Container **/
166
+ .monsterinsights-sub-nav-container{display:table-cell;float:none;vertical-align:top;background-color:#f7f8fa;float:left;width:270px;margin:0;padding:0;border-left:1px solid #e4e9ee;border-top:1px solid #e4e9ee;border-bottom:1px solid #e4e9ee;border-right:1px solid #e4e9ee;border-collapse:collapse;border-top-left-radius:3px;border-bottom-left-radius:3px}
167
+
168
+ /** Nav Item **/
169
+ /** Generic **/
170
+ .monsterinsights-nav-item{border:none;float:left;text-decoration: none;}
171
+ .monsterinsights-nav-item:focus,.monsterinsights-nav-item:active{box-shadow: none;}
172
+
173
+ /** Main Nav Item **/
174
+ .monsterinsights-main-nav-item{background-color:#615d9b;color:#d8d7e4;background:none;line-height:50px;font-size:13px;padding:0 15px;margin:0;width:100px;text-align:center}
175
+ .monsterinsights-main-nav-item.monsterinsights-spacing-item{width:5px;padding-left: 0;}
176
+ .monsterinsights-main-nav-item.monsterinsights-active{color:#434751;opacity:1;background-color:#fff}
177
+ .monsterinsights-main-nav-item:hover:not(.monsterinsights-active),.monsterinsights-main-nav-item:active:not(.monsterinsights-active){color:#fff;opacity:1}
178
+ .monsterinsights-main-nav-container > .monsterinsights-main-nav-item:not(.monsterinsights-active) + a.monsterinsights-main-nav-item:not(.monsterinsights-active) {border-left: 1px solid #8c8ab5;}
179
+ .monsterinsights-main-nav-container > .monsterinsights-main-nav-item:last-child:not(.monsterinsights-active) {border-right: 1px solid #8c8ab5;}
180
+ .monsterinsights-main-nav-item.monsterinsights-active{border:0 !important}
181
+
182
+ /** Sub Nav Item **/
183
+ .monsterinsights-sub-nav-item{font-size:13px;background-color:#f7f8fa;font-weight:500;line-height:50px;width:270px;margin:0;padding:5px 0 5px 8px;text-decoration:none;color:#7f8591;border-bottom:1px solid #e4e9ee;border-right:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;box-shadow:none;-webkit-box-shadow:none;-webkit-transition:none;}
184
+ .monsterinsights-sub-nav-item.monsterinsights-active,.monsterinsights-sub-nav-item:hover,.monsterinsights-sub-nav-item:active{width:270px;border-right:1px solid #fff;background-color:#fff;color:#444851}
185
+
186
+ /** Nav Tab Container **/
187
+ /** Generic **/
188
+ .monsterinsights-sub-nav-area { display: flex;} /* Holds Sub nav menu and tabs */
189
+ .monsterinsights-nav-tabs{}
190
+
191
+ /** Main Nav Tab Container **/
192
+ .monsterinsights-main-nav-tabs{}
193
+
194
+ /** Sub Nav Tab Container **/
195
+ .monsterinsights-sub-nav-tabs{float:left;display:table-cell;float:none;vertical-align:top;background-color:#f7f8fa;border-top:1px solid #e4e9ee;border-right:1px solid #e4e9ee;border-bottom:1px solid #e4e9ee;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;box-shadow:none;-webkit-box-shadow:none;-webkit-transition:none;border-top-right-radius:3px;border-bottom-right-radius:3px;width:100%;}
196
+
197
+ /** Nav Tab **/
198
+ /** Generic **/
199
+ .monsterinsights-nav-tab{display:none;}
200
+ .monsterinsights-nav-tab.monsterinsights-active{display:block}
201
+ .monsterinsights-nav-tab .description{color:#7f8592;font-size:13px;margin-top:10px}
202
+
203
+ /** Main Nav Tab **/
204
+ .monsterinsights-main-nav-tab{}
205
+ .monsterinsights-main-nav-tab .form-table tr{border-bottom:1px solid #ddd}
206
+ .monsterinsights-main-nav-tab .form-table tr.no-bottom-border{border-bottom:0}
207
+
208
+ /** Sub Nav Tab **/
209
+ .monsterinsights-sub-nav-tab{margin:15px 0 20px;}
210
+ .monsterinsights-sub-nav-tab .form-table tr{border-bottom:1px solid #ddd}
211
+ .monsterinsights-sub-nav-tab .form-table tr.no-bottom-border{border-bottom:0}
212
+
213
+ /** Nav Media Queries **/
214
+ .monsterinsights-main-nav-tabs .form-table th,.monsterinsights-main-nav-tabs .form-table td {padding-top: 40px;padding-bottom: 40px;}
215
+ .monsterinsights-sub-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table td { padding-top: 40px;}
216
+ @media (min-width: 768px) and (max-width: 991px) {
217
+ .monsterinsights-main-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table th{padding-top:40px;padding-right:0!important}
218
+ .monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-right:0}
219
+ }
220
+ @media (min-width: 600px) and (max-width: 767px) {
221
+ .monsterinsights-main-nav-tabs .form-table th, .monsterinsights-sub-nav-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0!important}
222
+ .monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-top:0;padding-right:0}
223
+ }
224
+ @media only screen and (max-width: 610px) {
225
+ .monsterinsights-main-nav-tabs .form-table th, .monsterinsights-sub-nav-tabs .form-table th{padding-top:20px;padding-bottom:10px;padding-right:0px}
226
+ .monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-top:0;padding-bottom:20px;padding-right:0px}
227
+ .monsterinsights-main-nav-item{width:auto}
228
+ .monsterinsights-main-nav-item.monsterinsights-spacing-item{display:none}
229
+ h1.monsterinsights-nav-container { padding: 0px; min-width: 150px;}
230
+ .monsterinsights-sub-nav-tabs th{width:auto}
231
+ }
232
+ @media only screen and (max-width: 767px) {
233
+ .monsterinsights-sub-nav-container{width:100%}
234
+ .monsterinsights-sub-nav-item{padding:0;text-align:center;width:100%!important;padding:0;text-align:center}
235
+ .monsterinsights-sub-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table td{padding:10px 0!important}
236
+ h1.monsterinsights-nav-container { padding: 0px;}
237
+ }
238
+
239
+ /** Settings Page Styles **/
240
+ /** Generic Settings Page Styles **/
241
+ div#monsterinsights-settings-sub-pages{padding-left:20px;background-color:#FFF;padding-right:20px}
242
+ #monsterinsights-settings-pages{padding:20px 0}
243
+ .monsterinsights-main-nav-tabs label{margin-top:7px;display:block;color:#444851}
244
+ .monsterinsights-sub-nav-tabs label{margin-top:7px;display:block}
245
+ #monsterinsights-settings-pages #monsterinsights-settings-submit{margin:40px 0 0 0px}
246
+ #monsterinsights-settings-pages #monsterinsights-refresh-submit{margin-left:10px;vertical-align:baseline;}
247
+ input.monsterinsights-large-checkbox{zoom:1.5}
248
+ #monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email], #monsterinsights-settings-pages select,#monsterinsights-settings-pages textarea{width:350px;padding-right:0;font-size:13px;border-width:2px;border-radius:3px;border-color:#e4e9ee;box-shadow:none}
249
+ #monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email]{height:32px;}
250
+ @media (max-width: 767px) {
251
+ #monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"], #monsterinsights-settings-pages input[type=email], #monsterinsights-settings-pages select,#monsterinsights-settings-pages textarea{width:90%!important}
252
+ #monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"], #monsterinsights-settings-pages input[type=email]{height:auto;}
253
+ }
254
+
255
+ /** General Tab Styles **/
256
+ /** License Key Styles */
257
+ @media (min-width: 768px) and (max-width: 991px) {
258
+ tr#monsterinsights-settings-key-box th{padding-top:20px}
259
+ }
260
+ @media (min-width: 600px) and (max-width: 767px) {
261
+ tr#monsterinsights-settings-key-box th{padding-top:20px}
262
+ }
263
+
264
+ /** GA Auth Styles */
265
+ /** Container */
266
+ .monsterinsights_opacity_60{opacity:.6}
267
+ #monsterinsights_google_auth_view{color:#000;font-family:"proxima-nova","Helvetica Neue",sans-serif;-webkit-transition:opacity 1s;-moz-transition:opacity 1s;-o-transition:opacity 1s;transition:opacity 1s;text-align:center;-webkit-perspective:700px;-webkit-perspective-origin:320px 700px;margin:0 auto;height:588px;width:400px;overflow:hidden;max-width:100%;margin:auto;top:0;left:0;bottom:0;right:0;position:absolute;z-index:300001;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#f3f5ff;-moz-box-shadow:0 0 43px rgba(97,93,155,.23);-webkit-box-shadow:0 0 43px rgba(97,93,155,.23);box-shadow:0 0 43px rgba(97,93,155,.23)}
268
+
269
+ /** Backgrounds */
270
+ .monsterinsights_google_auth_start_view{background-image:url(../images/gauth-1-of-3.png);background-repeat:no-repeat}
271
+ .monsterinsights_google_auth_exit_view{background-image:url(../images/gauth-exit.png);background-repeat:no-repeat}
272
+ .monsterinsights_google_auth_enterkey_view{background-image:url(../images/gauth-2-of-3.png);background-repeat:no-repeat}
273
+ .monsterinsights_google_auth_selectprofile_view{background-image:url(../images/gauth-3-of-3.png);background-repeat:no-repeat}
274
+ .monsterinsights_google_auth_done_view{background-image:url(../images/gauth-done.png);background-repeat:no-repeat}
275
+ .monsterinsights_google_auth_reauth_start_view{background-image:url(../images/gauth-warn-1-of-3.png);background-repeat:no-repeat}
276
+ .monsterinsights_google_auth_reauth_exit_view{background-image:url(../images/gauth-warn-exit.png);background-repeat:no-repeat}
277
+ .monsterinsights_google_auth_reauth_enterkey_view{background-image:url(../images/gauth-warn-2-of-3.png);background-repeat:no-repeat}
278
+ .monsterinsights_google_auth_reauth_selectprofile_view{background-image:url(../images/gauth-warn-3-of-3.png);background-repeat:no-repeat}
279
+ .monsterinsights_google_auth_reauth_done_view{background-image:url(../images/gauth-warn-done.png);background-repeat:no-repeat}
280
+ @media only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 21),only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min-device-pixel-ratio: 2) {
281
+ .monsterinsights_google_auth_start_view{background-image:url(../images/gauth-1-of-3@2x.png);background-size:400px 588px}
282
+ .monsterinsights_google_auth_exit_view{background-image:url(../images/gauth-exit@2x.png);background-size:400px 588px}
283
+ .monsterinsights_google_auth_enterkey_view{background-image:url(../images/gauth-2-of-3@2x.png);background-size:400px 588px}
284
+ .monsterinsights_google_auth_selectprofile_view{background-image:url(../images/gauth-3-of-3@2x.png);background-size:400px 588px}
285
+ .monsterinsights_google_auth_done_view{background-image:url(../images/gauth-done@2x.png);background-size:400px 588px}
286
+ .monsterinsights_google_auth_reauth_start_view{background-image:url(../images/gauth-warn-1-of-3@2x.png);background-size:401px 651px}
287
+ .monsterinsights_google_auth_reauth_exit_view{background-image:url(../images/gauth-warn-exit@2x.png);background-size:401px 651px}
288
+ .monsterinsights_google_auth_reauth_enterkey_view{background-image:url(../images/gauth-warn-2-of-3@2x.png);background-size:401px 651px}
289
+ .monsterinsights_google_auth_reauth_selectprofile_view{background-image:url(../images/gauth-warn-3-of-3@2x.png);background-size:401px 651px}
290
+ .monsterinsights_google_auth_reauth_done_view{background-image:url(../images/gauth-warn-done@2x.png);background-size:401px 651px}
291
+ }
292
+
293
+ /** Header/Footer */
294
+ #monsterinsights_google_auth_block_view{position:fixed;background:rgba(243,246,255,.9);top:0;right:0;bottom:0;left:0;z-index:300000}
295
+ #monsterinsights_google_auth_box_header{height:80px;width:100%}
296
+ #monsterinsights_google_auth_box_contents{height:187px;padding-top:321px;width:100%}
297
+ #monsterinsights_google_auth_box_contents.monsterinsights_google_auth_reauth{padding-top:303px}
298
+ #monsterinsights_google_auth_box_footer{height:80px;width:100%}
299
+ .monsterinsights_google_auth_box_header_reauth{color:#434751;font-size:14px;padding-left:90px;padding-top:23px;text-align:left}
300
+ .monsterinsights_google_auth_box_header_reauth .monsterinsights_google_auth_box_cancel{color:#FFF;opacity:1}
301
+ .monsterinsights_google_auth_start_view_description{color:#7f8591;font-size:14px;padding-bottom:40px}
302
+ .monsterinsights_google_auth_view_title{color:#434751;font-size:20px;padding-bottom:27px}
303
+ .monsterinsights_google_auth_box_cancel:hover{color:#fff;font-size:16px;font-weight:700;text-decoration:none;opacity:1}
304
+ .monsterinsights_google_auth_box_cancel{opacity:.5;color:#fff;font-size:16px;font-weight:700;text-decoration:none}
305
+ #monsterinsights_google_auth_box_footer_center{width:175px;float:left}
306
+ #monsterinsights_google_auth_box_footer_left,#monsterinsights_google_auth_box_footer_right{width:125px;float:left}
307
+ div#monsterinsights_google_auth_box_footer_right_next{padding-top:13px}
308
+ #monsterinsights_google_auth_box_footer_right{color:#fff;font-size:16px;font-weight:700;margin-top:20px;width:85px;height:45px}
309
+ #monsterinsights_google_auth_box_footer_right:hover{background-color:#524e86}
310
+ .monsterinsights_google_auth_box_cancel_error:focus,.monsterinsights_google_auth_box_cancel_error,.monsterinsights_google_auth_box_done:focus,.monsterinsights_google_auth_box_done,.monsterinsights_google_auth_box_next:focus,.monsterinsights_google_auth_box_next{text-decoration:none;color:#fff}
311
+ .monsterinsights_google_auth_box_cancel_error:hover,.monsterinsights_google_auth_box_done:hover,.monsterinsights_google_auth_box_next:hover{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;margin-top:10px;color:#fff}
312
+ #monsterinsights_google_auth_box_footer_left{padding-top:34px}
313
+
314
+ /** Misc Styles */
315
+ #monsterinsights-google-oauth-window{width:80%;margin-right:10%;margin-left:10%;margin-bottom:10px}
316
+ #monsterinsights_google_auth_view.monsterinsights_google_auth_reauth{height:650px}
317
+ .monsterinsights_google_auth_step_data_enterkey_view{width:80%;margin-right:10%;margin-left:10%;height:30px;margin-top:10px}
318
+ .monsterinsights-google-loading{width:100%;height:100%;background-color:#FFF;color:#000;font-size:30px;padding-top:30px}
319
+ body.monsterinsights_page .select2-container--open{z-index:300002 !important}
320
+
321
+ /** Tracking Tab Styles **/
322
+ /** Upgrade CSS */
323
+ .monsterinsights-upsell-box{background-color:#f6fbff;border:1px solid #d6ecff;border-radius:3px;padding:10px 20px}
324
+ a.monsterinsights-upsell-box-button.button.button-primary{margin-top:20px}
325
+
326
+ /** Status Tab Styles **/
327
+
328
+ /** Support Tab Styles **/
329
+
330
+ /** Settings Page Media Queries **/
331
+
332
+ /** Dashboard Page Styles **/
333
+ /** Dashboard Page Styles **/
334
+
335
+ /** Dashboard Page Media Queries **/
336
+
337
+ /** Reports Page Styles **/
338
+ /** Generic Reports Page Styles **/
339
+ .monsterinsights-reports-action-bar-title{font-size:24px;font-weight:700;float:left}
340
+ #monsterinsights-reports-pages{margin-top:30px}
341
+ .monsterinsights-grid-border{border:1px solid #e3e9ed;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
342
+ .monsterinsights-grid-grey-bg{background-color:#f7f7f9;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box}
343
+ @media (max-width: 600px) {
344
+ .monsterinsights-grid > .monsterinsights-col-1-2{width:100%;margin-top:50px}
345
+ }
346
+
347
+ /** Overview Report Styles **/
348
+ .monsterinsights-data-row{width:100%;float:left;box-sizing:border-box;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;color:#7f8591;padding:10px 15px}
349
+ .monsterinsights-data-row .monsterinsights-col-7-8{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}
350
+ .monsterinsights-reports-box-datalist .monsterinsights-data-row:nth-child(odd){background-color:#f7f7f9}
351
+ .monsterinsights-reports-box-title{background-color:#FFF;color:#7f8591;font-size:14px;font-weight:700;padding:20px;border-bottom:1px solid #e3e9ed;border-top-left-radius:5px;border-top-right-radius:5px}
352
+ .monsterinsights-reports-box-datagraph{border:1px solid #e3e9ed;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff;margin:20px;width:auto;padding:20px}
353
+ .monsterinsights-no-padding-right{padding-right:0}
354
+ .monsterinsights-datalist-box-title{color:#7f8591;font-size:14px;font-weight:700;margin-bottom:10px}
355
+ .monsterinsights-reports-action-bar{padding-bottom:40px;margin-top:40px}
356
+ .monsterinsights-reports-action-bar-actions{float:right}
357
+ #monsterinsights-chartjs-tooltip{opacity:1;position:absolute;-webkit-transition:all .1s ease;transition:all .1s ease;pointer-events:none;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);border:1px solid #e3e9ed;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff;-moz-box-shadow:0 0 20px rgba(97,93,155,.13);-webkit-box-shadow:0 0 20px rgba(97,93,155,.13);box-shadow:0 0 20px rgba(97,93,155,.13);color:#434751;font-size:18px;font-weight:700;padding:8px!important}
358
+ /** Reports Page Media Queries **/
359
+
360
+ /** Tools Page Styles **/
361
+ /** Generic Tools Page Styles **/
362
+
363
+ /** URL Generator Tab Styles **/
364
+
365
+ /** Import/Export Tab Styles **/
366
+
367
+ /** Tools Page Media Queries **/
368
+
369
+ /** Addons Page Styles **/
370
+ /** Addons Font */
371
+ @font-face{font-family:'monsterinsights';src:url(../fonts/monsterinsights.eot);src:url(../fonts/monsterinsights.eot?#iefix) format("embedded-opentype"),url(../fonts/monsterinsights.woff) format("woff"),url(../fonts/monsterinsights.ttf) format("truetype"),url(../fonts/monsterinsights.svg#monsterinsights) format("svg");font-weight:400;font-style:normal}
372
+ #monsterinsights-addons [class*='monsterinsights-']:before{display:inline-block;font-family:'monsterinsights';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
373
+ #monsterinsights-addons .monsterinsights-configuration:before{content:'\0041'}
374
+ #monsterinsights-addons .monsterinsights-leaf:before{content:'\0042'}
375
+ #monsterinsights-addons .monsterinsights-lightbox:before{content:'\0044'}
376
+ #monsterinsights-addons .monsterinsights-misc:before{content:'\0045'}
377
+ #monsterinsights-addons .monsterinsights-mobile:before{content:'\0046'}
378
+ #monsterinsights-addons .monsterinsights-pagination:before{content:'\0047'}
379
+ #monsterinsights-addons .monsterinsights-proofing:before{content:'\0048'}
380
+ #monsterinsights-addons .monsterinsights-slideshow:before{content:'\0049'}
381
+ #monsterinsights-addons .monsterinsights-tags:before{content:'\004a'}
382
+ #monsterinsights-addons .monsterinsights-thumbnails:before{content:'\004b'}
383
+ #monsterinsights-addons .monsterinsights-video:before{content:'\004c'}
384
+ #monsterinsights-addons .monsterinsights-watermark:before{content:'\004d'}
385
+ #monsterinsights-addons .monsterinsights-cloud-download:before{content:'\004e'}
386
+ #monsterinsights-addons .monsterinsights-toggle-on:before{content:'\004f'}
387
+ #monsterinsights-addons .monsterinsights-plus-circle:before{content:'\0050'}
388
+ #monsterinsights-addons .monsterinsights-down-arrow:before{content:'\0051'}
389
+ #monsterinsights-addons .monsterinsights-list:before{content:'\0052'}
390
+ /* #monsterinsights-addons .monsterinsights-grid:before{content:'\0053'}*/
391
+ #monsterinsights-addons .monsterinsights-pinterest-p:before{content:'\0054'}
392
+ #monsterinsights-addons .monsterinsights-pencil:before{content:'\0055'}
393
+ #monsterinsights-addons .monsterinsights-close:before{content:'\0056'}
394
+ #monsterinsights-addons .monsterinsights-check:before{content:'\0057'}
395
+
396
+ /** Generic Addons Page Styles **/
397
+ body.monsterinsights_page .monsterinsights-addons-subheading{background-color:#fff;height:45px;margin-left:-20px}
398
+ body.monsterinsights_page .monsterinsights-addons-subheading h1{font-size:20px;font-weight:400;line-height:45px;margin:0 0 0 20px;padding-left:20px}
399
+ @media (min-width: 600px) and (max-width: 767px) {
400
+ body.monsterinsights_page .monsterinsights-addons-subheading{height:auto;padding-bottom:20px}
401
+ }
402
+ #monsterinsights-addon-heading:after{content:"";display:table;clear:both}
403
+ #monsterinsights-addon-heading h1{float:left}
404
+ #monsterinsights-addon-heading form{float:right;margin-right:100px}
405
+ @media (min-width: 600px) and (max-width: 767px) {
406
+ #monsterinsights-addon-heading h1{float:none}
407
+ }
408
+ @media (max-width: 508px) {
409
+ #monsterinsights-addon-heading form{display:none}
410
+ }
411
+ @media (max-width: 600px) {
412
+ .monsterinsights-addon .interior{display:none!important}
413
+ }
414
+ #monsterinsights-addon-heading form input{border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px;background-color:#fff;color:#666;margin:7px 10px 0 5px;font-size:14px;padding:5px 8px}
415
+ #monsterinsights-addon-heading form select{margin:-5px 20px 0 0}
416
+ #monsterinsights-addon-heading form .spinner{float:none;margin:-3px auto auto}
417
+ @media (min-width: 600px) and (max-width: 767px) {
418
+ #monsterinsights-addon-heading form{float:none;display:table;margin:10px auto 0}
419
+ }
420
+
421
+ #monsterinsights-addons{padding:0px;}
422
+ #monsterinsights-addons .button,#monsterinsights-addons .button-primary{text-shadow:none;background-color:#f7f7f7;color:#23282d;font-weight:600;border:1px solid #ccc;line-height:inherit;height:inherit;padding:5px 15px;box-shadow:none;cursor:pointer}
423
+ #monsterinsights-addons .button:hover,#monsterinsights-addons .button-primary:hover{color:#23282d;background-color:#fafafa;border-color:#999}
424
+ #monsterinsights-addons .monsterinsights-addon-action-button{padding-left:20px;padding-right:20px}
425
+ #monsterinsights-addons .monsterinsights-addon-action-button .monsterinsights-cloud-download{font-size:19px;float:left;margin-right:8px;color:#8d8f92}
426
+ #monsterinsights-addons .monsterinsights-addon-action-button .monsterinsights-toggle-on{font-size:19px;float:left;margin-right:8px;margin-top:1px;color:#7cc048}
427
+ #monsterinsights-addons .monsterinsights-addon-upgrade-button{background-color:#7cc048;color:#fff;float:none!important;margin:0 auto;display:table;line-height:25px}
428
+ #monsterinsights-addons .monsterinsights-addon-upgrade-button:hover{background-color:#95dc5e;color:#fff;border-color:#95dc5e}
429
+ #monsterinsights-addons .monsterinsights-addon-action-button.monsterinsights-activate-addon .monsterinsights-toggle-on{color:#e92c21;-moz-transform:scaleX(-1);-o-transform:scaleX(-1);-webkit-transform:scaleX(-1);transform:scaleX(-1);filter:FlipH;-ms-filter:FlipH}
430
+ #monsterinsights-addons .monsterinsights-addon-title{margin-top:30px}
431
+ #monsterinsights-addons .monsterinsights-addons-area:after{content:"";display:table;clear:both}
432
+ #monsterinsights-addons .monsterinsights-addons-area.licensed{margin:20px 0 40px;padding:0 0 20px;border-bottom:1px solid #ddd}
433
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{border:1px solid #ddd;position:relative;background:#fff;border-radius:3px;float:left;margin:0 2% 2% 0;min-height:465px;padding:0;text-align:center;width:32%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}
434
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon:nth-child(3n){margin-right:0}
435
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon:nth-child(3n+1){clear:both}
436
+ @media (min-width: 992px) and (max-width: 1199px) {
437
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{min-height:420px}
438
+ }
439
+ @media (min-width: 768px) and (max-width: 991px) {
440
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{width:100%!important;min-height:525px}
441
+ }
442
+ @media (min-width: 600px) and (max-width: 767px) {
443
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{width:100%!important;min-height:525px}
444
+ }
445
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:20px auto;max-width:100%}
446
+ @media (min-width: 992px) and (max-width: 1199px) {
447
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}
448
+ }
449
+ @media (min-width: 768px) and (max-width: 991px) {
450
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}
451
+ }
452
+ @media (min-width: 600px) and (max-width: 767px) {
453
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}
454
+ }
455
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{color:#2f2f2f;font-weight:400;padding:0 20px;display:table;margin:0 0 90px}
456
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message{background:#f7f7f7;border-top:1px solid #ddd}
457
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error{position:absolute;bottom:0;float:left;width:100%;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;margin:0;padding:0;text-align:left}
458
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message .interior,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .interior{padding:20px}
459
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message .interior:after,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .interior:after{content:"";display:table;clear:both}
460
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .addon-status span{color:#7cc048}
461
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}
462
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}
463
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}
464
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .addon-status span{color:#e82c20}
465
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}
466
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}
467
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}
468
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}
469
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}
470
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}
471
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}
472
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.addon-status,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error span.addon-status{float:left;font-weight:700}
473
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message a.button,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error a.button{float:right}
474
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.monsterinsights-spinner,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error span.monsterinsights-spinner{position:absolute;bottom:15px;right:0}
475
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action{display:inline;float:right}
476
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary{margin:-5px 0 0;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px}
477
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary:hover{color:#23282d;background-color:#fafafa;border-color:#999}
478
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error{bottom:10px;float:none;left:15px;right:20px;width:auto}
479
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .xinterior{width:100%;margin:0;background:#fff;border-left:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1)}
480
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error p{padding:10px;margin:5px 10px}
481
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .wrap{margin:0}
482
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .icon32{display:none}
483
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error h2{padding:0}
484
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .form-table th{padding:10px 0;width:30%!important}
485
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .form-table input[type="text"],#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .monsterinsights-addon .monsterinsights-addon-error .form-table input[type="password"]{width:100%!important}
486
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error p.submit{padding:0}
487
+ #monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon p{color:#2f2f2f;font-size:13px;margin:10px 0 0;text-shadow:0 1px #fff}
488
+ #monsterinsights-addons .monsterinsights-addons-area #monsterinsights-addons-unlock-more-area{margin:40px auto 20px;padding-bottom:0;border-bottom:0}
489
+ #monsterinsights-addons-more-area .monsterinsights-addon .interior{padding:15px 20px!important}
490
+ #monsterinsights-addons-refresh-addons-form{width:100%;max-width:850px;float:left}
491
+ @media (min-width: 992px) and (max-width: 1199px) {
492
+ #monsterinsights-addons-refresh-addons-form{max-width:450px}
493
+ }
494
+ @media (min-width: 768px) and (max-width: 991px) {
495
+ #monsterinsights-addons-refresh-addons-form{max-width:50%}
496
+ #monsterinsights-addons-refresh-addons-form input.button{display:block}
497
+ }
498
+ @media (min-width: 600px) and (max-width: 767px) {
499
+ #monsterinsights-addons-refresh-addons-form{width:100%;float:none}
500
+ #monsterinsights-addons-refresh-addons-form input.button{display:block}
501
+ }
502
+ #monsterinsights-filter-form{float:right}
503
+ #monsterinsights-filter-form input[type='submit'],#monsterinsights-filter-form select{background-color:#f7f7f7;color:#23282d;border:1px solid #ddd;height:30px;width:120px;margin-top:-2px}
504
+ #monsterinsights-filter-form input{padding:5px 15px;box-shadow:0;cursor:pointer;background-color:#f7f7f7;color:#23282d}
505
+ #monsterinsights-filter-form input:hover{color:#23282d;background-color:#fafafa;border-color:#999}
506
+ #monsterinsights-filter-form .spinner{float:left}
507
+ @media only screen and (max-width: 1050px) {
508
+ #monsterinsights-addons-area .monsterinsights-addon{width:49%}
509
+ #monsterinsights-addons-area .monsterinsights-addon:nth-child(2n){margin-right:0}
510
+ #monsterinsights-addons-area .monsterinsights-addon:nth-child(2n+1){clear:both}
511
+ #monsterinsights-addons-area .monsterinsights-addon:nth-child(3n){margin-right:2%}
512
+ #monsterinsights-addons-area .monsterinsights-addon:nth-child(3n+1){clear:none}
513
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{margin-bottom:90px}
514
+ }
515
+ @media only screen and (max-width: 782px) {
516
+ #monsterinsights-addons-area .monsterinsights-addon{min-height:auto}
517
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary{margin:-7px 0 0}
518
+ }
519
+ @media only screen and (max-width: 600px) {
520
+ #monsterinsights-addons-area .monsterinsights-addon{width:99%}
521
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message{float:left;width:100%}
522
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.addon-status{display:block;width:100%;margin:0 0 5px;text-align:center}
523
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message div.monsterinsights-addon-action{clear:both;display:block;width:100%;text-align:center}
524
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message div.monsterinsights-addon-action .button-primary{clear:both;float:none;margin:0 auto}
525
+ #monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{margin-bottom:120px}
526
+ }
527
+ /** Network Addons Page Styles **/
528
+
529
+ /** Single Site Addons Page Styles **/
530
+
531
+ /** Welcome Page Styles **/
532
+ /** Generic Welcome Page Styles **/
533
+
534
+ /** Welcome Tab Styles **/
535
+
536
+ /** What's New Tab Styles **/
537
+
538
+ /** Changelog Tab Styles **/
539
+
540
+ /** Support Tab Styles **/
assets/css/admin.min.css ADDED
@@ -0,0 +1 @@
 
1
+ body.monsterinsights_page div.wrap > div.error,body.monsterinsights_page div.wrap > div.notice,body.monsterinsights_page div.wrap > div.updated{margin-left:20px;margin-right:20px}body.monsterinsights_page .update-nag{margin-left:20px;margin-bottom:20px}body.monsterinsights_page #wpcontent{padding-left:0}body.monsterinsights_page div.wrap{margin:0 20px}body.monsterinsights_page #wpbody,body.monsterinsights_page #wpfooter,body.monsterinsights_page,body.monsterinsights_page #wpwrap{background-color:#fff}@media (max-width: 599px){body.monsterinsights_page #wpbody{padding-top:0}}.monsterinsights-grid{margin:0 0 50px}.monsterinsights-grid:after{content:"";display:table;clear:both}.monsterinsights-col-1-1{width:100%}.monsterinsights-col-7-8{width:87.5%}.monsterinsights-col-3-4{width:75%}.monsterinsights-col-2-3{width:66.66%}.monsterinsights-col-1-2{width:50%}.monsterinsights-col-1-3{width:33.33%}.monsterinsights-col-1-4{width:25%}.monsterinsights-col-1-8{width:12.5%}[class*="monsterinsights-col-"]{float:left;padding-right:20px;box-sizing:border-box}.monsterinsights-grid [class*="monsterinsights-col-"]:last-of-type{padding-right:0}.monsterinsights-hideme{display:none;visibility:hidden}.monsterinsights-no-text-decoration{text-decoration:none}.monsterinsights-clear{clear:both}.monsterinsights-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}.monsterinsights-clearfix{content:"";display:table;clear:both}.monsterinsights-clearfix-after:after{content:"";display:table;clear:both}.monsterinsights-help-tip{cursor:help}.monsterinsights-ui-tooltip{background:#333 !important;border-width:1px !important;border-radius:3px !important;box-shadow:1px 1px 2px 1px rgba(214,214,214,0.5) !important;color:#dedede !important;max-width:300px !important;padding:7px !important;text-rendering:optimizeLegibility;text-shadow:none !important;z-index:9999 !important}body.monsterinsights_page .button{-webkit-border-radius:2px;-moz-border-radius:2px;-o-border-radius:2px;border-radius:2px;padding:0 16px 1px;height:33px;line-height:30px;text-decoration:none;text-shadow:none;font-weight:600;-webkit-box-shadow:none;box-shadow:none}body.monsterinsights_page .button.button-small{padding:0 8px 1px;line-height:22px;height:24px}body.monsterinsights_page .button.button-x-large{padding:0 32px 1px;line-height:48px;height:50px;font-size:18px;text-transform:uppercase}body.monsterinsights_page .button.show-settings{height:auto}body.monsterinsights_page .button.button-primary{background:#47c1a5;border-color:#3ca489;-webkit-box-shadow:none;box-shadow:none;color:#fff;border:1px solid #3ca489;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#47c1a5}body.monsterinsights_page .button.button-primary:hover{background:#3ba389;border-color:#3ba389;color:#fff}body.monsterinsights_page .button.button-action{background:#479be7;border-color:#4182bf;-webkit-box-shadow:none;box-shadow:none;color:#fff;border:1px solid #4182bf;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#479be7}body.monsterinsights_page .button.button-action:hover{background:#4183bf;border-color:#4183bf;color:#fff}body.monsterinsights_page .button.button-danger{background:#fff;border-color:#e3e9ed;-webkit-box-shadow:none;box-shadow:none;color:#000;border:1px solid #e3e9ed;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff}body.monsterinsights_page .button.button-danger:hover{background:#e3e9ed;border-color:#e3e9ed;color:#000}@media (min-width: 600px) and (max-width: 767px){body.monsterinsights_page .button{margin-top:10px}}div.monsterinsights-code{position:relative;margin:0 0 10px}div.monsterinsights-code:after{content:"";display:table;clear:both}div.monsterinsights-code code{display:block;font-size:11px;padding:5px 20px 5px 5px}a.monsterinsights-clipboard{position:absolute;top:5px;right:5px;color:#23282d;width:33px;padding:0}a.monsterinsights-clipboard span{display:block;text-indent:-9999px}#monsterinsights-header-temp{position:relative;margin:0}#monsterinsights-header{background-color:#f3f5ff;background-image:url(images/waves.png);background-repeat:no-repeat;margin:0;height:119px}@media only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 21),only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min-device-pixel-ratio: 2){#monsterinsights-header{background-image:url(images/waves@x2.png);background-size:1356px 119px}}.monsterinsights-header-title{padding-top:50px;padding-left:20px;margin:0}.monsterinsights-header-mascot{float:right;position:absolute;top:0;right:0;margin-top:10px;margin-right:20px;z-index:100}@media (max-width: 610px){.monsterinsights-header-mascot{display:none}.monsterinsights-header-title{padding-top:70px}#monsterinsights-addon-heading form{margin-right:0}}.monsterinsights-notice{border:1px solid;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;box-sizing:border-box;display:table;width:100%;margin:10px 0px}.monsterinsights-notice:after{content:"";display:table;clear:both}.monsterinsights-notice-icon{padding:20px;box-sizing:border-box;width:60px;color:#fff;font-family:"FontAwesome";font-size:18px;-moz-border-radius:5px 0 0;-webkit-border-radius:5px 0 0;border-radius:5px 0 0;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;display:table-cell;vertical-align:middle;text-align:center}.monsterinsights-notice-text{color:#434751;font-size:16px;font-weight:700;padding:0px 60px 0px 20px;box-sizing:border-box;word-wrap:break-word;display:table-cell;position:relative;vertical-align:middle}body.monsterinsights_page div.wrap > div.error,body.monsterinsights_page div.wrap > div.notice,body.monsterinsights_page div.wrap > div.updated{margin-left:0;margin-right:0}.monsterinsights-notice .button{margin:0px 0px 1em 0px}.monsterinsights-alert-notice-icon{background-color:#fdbf2f}.monsterinsights-alert-notice{border-color:#fdbf2f;background-color:rgba(253,192,47,0.1)}.monsterinsights-error-notice-icon{background-color:#df4228}.monsterinsights-error-notice{border-color:#df4228;background-color:rgba(224,66,40,0.1)}.monsterinsights-info-notice-icon{background-color:#479be7}.monsterinsights-info-notice{border-color:#479be7;background-color:rgba(72,155,232,0.1)}.monsterinsights-success-notice-icon{background-color:#47c1a5}.monsterinsights-success-notice{border-color:#47c1a5;background-color:rgba(71,194,165,0.1)}.monsterinsights-notice p.monsterinsights-intro{border:none !important;margin:0 0 20px !important;padding:0 !important}.monsterinsights-notice .notice-dismiss{top:10px;right:10px;color:#000}.monsterinsights-notice .notice-dismiss:before{color:#000;width:26px;height:26px;font-size:22px}@font-face{font-family:'MISettings';src:url(../fonts/MISettings.eot);src:url(../fonts/MISettings.eot?#iefix) format("embedded-opentype"),url(../fonts/MISettings.woff) format("woff"),url(../fonts/MISettings.ttf) format("truetype"),url(../fonts/MISettings.svg#MISettings) format("svg");font-weight:400;font-style:normal}[class*='monstericon-']:before{display:inline-block;font-family:'MISettings';font-style:normal;font-weight:400;line-height:50px;padding-right:7px;padding-left:5px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:middle}[class*='monstericon-'].monsterinsights-active:before{color:#479be7}[class*='monstericon-']:active:before{color:#479be7}[class*='monstericon-']:hover:before{color:#479be7}.monstericon-ads:before{content:'\0041'}.monstericon-affiliates:before{content:'\0042'}.monstericon-compatibility:before{content:'\0043'}.monstericon-demographics:before{content:'\0044'}.monstericon-dimensions:before{content:'\0045'}.monstericon-files:before{content:'\0046'}.monstericon-ecommerce:before{content:'\0047'}.monstericon-engagement:before{content:'\0048'}.monstericon-forms:before{content:'\0049'}.monstericon-links:before{content:'\004a'}.monstericon-memberships:before{content:'\004b'}.monstericon-notifications:before{content:'\004c'}.monstericon-performance:before{content:'\004d'}.monstericon-permissions:before{content:'\004e'}.monstericon-reporting:before{content:'\004f'}.monstericon-social:before{content:'\0050'}.monstericon-media:before{content:'\0051'}.monsterinsights-upgrade-menu-icon{float:right;color:#7f8591;font-size:10px;font-weight:700;text-transform:uppercase;line-height:1;display:inline-block;padding:6px 12px;background-color:#fff;border-radius:3px;margin-right:18px;margin-top:15px}.monsterinsights-main-nav-item.monsterinsights-active .monsterinsights-upgrade-menu-icon,.monsterinsights-main-nav-item:hover .monsterinsights-upgrade-menu-icon{background-color:#f7f8fa}@media only screen and (max-width: 767px){[class*='monstericon-']:before{display:none !important;content:''}span.monsterinsights-upgrade-menu-icon{display:none}}.monsterinsights-nav-container{border:0;background-color:#615d9b;margin:0;display:table;width:100%}h1.monsterinsights-nav-container{padding:0px}.monsterinsights-main-nav-container{height:50px}.monsterinsights-sub-nav-container{display:table-cell;float:none;vertical-align:top;background-color:#f7f8fa;float:left;width:270px;margin:0;padding:0;border-left:1px solid #e4e9ee;border-top:1px solid #e4e9ee;border-bottom:1px solid #e4e9ee;border-right:1px solid #e4e9ee;border-collapse:collapse;border-top-left-radius:3px;border-bottom-left-radius:3px}.monsterinsights-nav-item{border:none;float:left;text-decoration:none}.monsterinsights-nav-item:focus,.monsterinsights-nav-item:active{box-shadow:none}.monsterinsights-main-nav-item{background-color:#615d9b;color:#d8d7e4;background:none;line-height:50px;font-size:13px;padding:0 15px;margin:0;width:100px;text-align:center}.monsterinsights-main-nav-item.monsterinsights-spacing-item{width:5px;padding-left:0}.monsterinsights-main-nav-item.monsterinsights-active{color:#434751;opacity:1;background-color:#fff}.monsterinsights-main-nav-item:hover:not(.monsterinsights-active),.monsterinsights-main-nav-item:active:not(.monsterinsights-active){color:#fff;opacity:1}.monsterinsights-main-nav-container > .monsterinsights-main-nav-item:not(.monsterinsights-active) + a.monsterinsights-main-nav-item:not(.monsterinsights-active){border-left:1px solid #8c8ab5}.monsterinsights-main-nav-container > .monsterinsights-main-nav-item:last-child:not(.monsterinsights-active){border-right:1px solid #8c8ab5}.monsterinsights-main-nav-item.monsterinsights-active{border:0 !important}.monsterinsights-sub-nav-item{font-size:13px;background-color:#f7f8fa;font-weight:500;line-height:50px;width:270px;margin:0;padding:5px 0 5px 8px;text-decoration:none;color:#7f8591;border-bottom:1px solid #e4e9ee;border-right:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;box-shadow:none;-webkit-box-shadow:none;-webkit-transition:none}.monsterinsights-sub-nav-item.monsterinsights-active,.monsterinsights-sub-nav-item:hover,.monsterinsights-sub-nav-item:active{width:270px;border-right:1px solid #fff;background-color:#fff;color:#444851}.monsterinsights-sub-nav-area{display:flex}.monsterinsights-sub-nav-tabs{float:left;display:table-cell;float:none;vertical-align:top;background-color:#f7f8fa;border-top:1px solid #e4e9ee;border-right:1px solid #e4e9ee;border-bottom:1px solid #e4e9ee;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;box-shadow:none;-webkit-box-shadow:none;-webkit-transition:none;border-top-right-radius:3px;border-bottom-right-radius:3px;width:100%}.monsterinsights-nav-tab{display:none}.monsterinsights-nav-tab.monsterinsights-active{display:block}.monsterinsights-nav-tab .description{color:#7f8592;font-size:13px;margin-top:10px}.monsterinsights-main-nav-tab .form-table tr{border-bottom:1px solid #ddd}.monsterinsights-main-nav-tab .form-table tr.no-bottom-border{border-bottom:0}.monsterinsights-sub-nav-tab{margin:15px 0 20px}.monsterinsights-sub-nav-tab .form-table tr{border-bottom:1px solid #ddd}.monsterinsights-sub-nav-tab .form-table tr.no-bottom-border{border-bottom:0}.monsterinsights-main-nav-tabs .form-table th,.monsterinsights-main-nav-tabs .form-table td{padding-top:40px;padding-bottom:40px}.monsterinsights-sub-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table td{padding-top:40px}@media (min-width: 768px) and (max-width: 991px){.monsterinsights-main-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table th{padding-top:40px;padding-right:0 !important}.monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-right:0}}@media (min-width: 600px) and (max-width: 767px){.monsterinsights-main-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0 !important}.monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-top:0;padding-right:0}}@media only screen and (max-width: 610px){.monsterinsights-main-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table th{padding-top:20px;padding-bottom:10px;padding-right:0px}.monsterinsights-main-nav-tabs .form-table td,.monsterinsights-sub-nav-tabs .form-table td{padding-top:0;padding-bottom:20px;padding-right:0px}.monsterinsights-main-nav-item{width:auto}.monsterinsights-main-nav-item.monsterinsights-spacing-item{display:none}h1.monsterinsights-nav-container{padding:0px;min-width:150px}.monsterinsights-sub-nav-tabs th{width:auto}}@media only screen and (max-width: 767px){.monsterinsights-sub-nav-container{width:100%}.monsterinsights-sub-nav-item{padding:0;text-align:center;width:100% !important;padding:0;text-align:center}.monsterinsights-sub-nav-tabs .form-table th,.monsterinsights-sub-nav-tabs .form-table td{padding:10px 0 !important}h1.monsterinsights-nav-container{padding:0px}}div#monsterinsights-settings-sub-pages{padding-left:20px;background-color:#FFF;padding-right:20px}#monsterinsights-settings-pages{padding:20px 0}.monsterinsights-main-nav-tabs label{margin-top:7px;display:block;color:#444851}.monsterinsights-sub-nav-tabs label{margin-top:7px;display:block}#monsterinsights-settings-pages #monsterinsights-settings-submit{margin:40px 0 0 0px}#monsterinsights-settings-pages #monsterinsights-refresh-submit{margin-left:10px;vertical-align:baseline}input.monsterinsights-large-checkbox{zoom:1.5}#monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email],#monsterinsights-settings-pages select,#monsterinsights-settings-pages textarea{width:350px;padding-right:0;font-size:13px;border-width:2px;border-radius:3px;border-color:#e4e9ee;box-shadow:none}#monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email]{height:32px}@media (max-width: 767px){#monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email],#monsterinsights-settings-pages select,#monsterinsights-settings-pages textarea{width:90% !important}#monsterinsights-settings-pages input[type="text"],#monsterinsights-settings-pages input[type="number"],#monsterinsights-settings-pages input[type="password"],#monsterinsights-settings-pages input[type=email]{height:auto}}@media (min-width: 768px) and (max-width: 991px){tr#monsterinsights-settings-key-box th{padding-top:20px}}@media (min-width: 600px) and (max-width: 767px){tr#monsterinsights-settings-key-box th{padding-top:20px}}.monsterinsights_opacity_60{opacity:.6}#monsterinsights_google_auth_view{color:#000;font-family:"proxima-nova","Helvetica Neue",sans-serif;-webkit-transition:opacity 1s;-moz-transition:opacity 1s;-o-transition:opacity 1s;transition:opacity 1s;text-align:center;-webkit-perspective:700px;-webkit-perspective-origin:320px 700px;margin:0 auto;height:588px;width:400px;overflow:hidden;max-width:100%;margin:auto;top:0;left:0;bottom:0;right:0;position:absolute;z-index:300001;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#f3f5ff;-moz-box-shadow:0 0 43px rgba(97,93,155,.23);-webkit-box-shadow:0 0 43px rgba(97,93,155,.23);box-shadow:0 0 43px rgba(97,93,155,.23)}.monsterinsights_google_auth_start_view{background-image:url(../images/gauth-1-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_exit_view{background-image:url(../images/gauth-exit.png);background-repeat:no-repeat}.monsterinsights_google_auth_enterkey_view{background-image:url(../images/gauth-2-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_selectprofile_view{background-image:url(../images/gauth-3-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_done_view{background-image:url(../images/gauth-done.png);background-repeat:no-repeat}.monsterinsights_google_auth_reauth_start_view{background-image:url(../images/gauth-warn-1-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_reauth_exit_view{background-image:url(../images/gauth-warn-exit.png);background-repeat:no-repeat}.monsterinsights_google_auth_reauth_enterkey_view{background-image:url(../images/gauth-warn-2-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_reauth_selectprofile_view{background-image:url(../images/gauth-warn-3-of-3.png);background-repeat:no-repeat}.monsterinsights_google_auth_reauth_done_view{background-image:url(../images/gauth-warn-done.png);background-repeat:no-repeat}@media only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 21),only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min-device-pixel-ratio: 2){.monsterinsights_google_auth_start_view{background-image:url(../images/gauth-1-of-3@2x.png);background-size:400px 588px}.monsterinsights_google_auth_exit_view{background-image:url(../images/gauth-exit@2x.png);background-size:400px 588px}.monsterinsights_google_auth_enterkey_view{background-image:url(../images/gauth-2-of-3@2x.png);background-size:400px 588px}.monsterinsights_google_auth_selectprofile_view{background-image:url(../images/gauth-3-of-3@2x.png);background-size:400px 588px}.monsterinsights_google_auth_done_view{background-image:url(../images/gauth-done@2x.png);background-size:400px 588px}.monsterinsights_google_auth_reauth_start_view{background-image:url(../images/gauth-warn-1-of-3@2x.png);background-size:401px 651px}.monsterinsights_google_auth_reauth_exit_view{background-image:url(../images/gauth-warn-exit@2x.png);background-size:401px 651px}.monsterinsights_google_auth_reauth_enterkey_view{background-image:url(../images/gauth-warn-2-of-3@2x.png);background-size:401px 651px}.monsterinsights_google_auth_reauth_selectprofile_view{background-image:url(../images/gauth-warn-3-of-3@2x.png);background-size:401px 651px}.monsterinsights_google_auth_reauth_done_view{background-image:url(../images/gauth-warn-done@2x.png);background-size:401px 651px}}#monsterinsights_google_auth_block_view{position:fixed;background:rgba(243,246,255,.9);top:0;right:0;bottom:0;left:0;z-index:300000}#monsterinsights_google_auth_box_header{height:80px;width:100%}#monsterinsights_google_auth_box_contents{height:187px;padding-top:321px;width:100%}#monsterinsights_google_auth_box_contents.monsterinsights_google_auth_reauth{padding-top:303px}#monsterinsights_google_auth_box_footer{height:80px;width:100%}.monsterinsights_google_auth_box_header_reauth{color:#434751;font-size:14px;padding-left:90px;padding-top:23px;text-align:left}.monsterinsights_google_auth_box_header_reauth .monsterinsights_google_auth_box_cancel{color:#FFF;opacity:1}.monsterinsights_google_auth_start_view_description{color:#7f8591;font-size:14px;padding-bottom:40px}.monsterinsights_google_auth_view_title{color:#434751;font-size:20px;padding-bottom:27px}.monsterinsights_google_auth_box_cancel:hover{color:#fff;font-size:16px;font-weight:700;text-decoration:none;opacity:1}.monsterinsights_google_auth_box_cancel{opacity:.5;color:#fff;font-size:16px;font-weight:700;text-decoration:none}#monsterinsights_google_auth_box_footer_center{width:175px;float:left}#monsterinsights_google_auth_box_footer_left,#monsterinsights_google_auth_box_footer_right{width:125px;float:left}div#monsterinsights_google_auth_box_footer_right_next{padding-top:13px}#monsterinsights_google_auth_box_footer_right{color:#fff;font-size:16px;font-weight:700;margin-top:20px;width:85px;height:45px}#monsterinsights_google_auth_box_footer_right:hover{background-color:#524e86}.monsterinsights_google_auth_box_cancel_error:focus,.monsterinsights_google_auth_box_cancel_error,.monsterinsights_google_auth_box_done:focus,.monsterinsights_google_auth_box_done,.monsterinsights_google_auth_box_next:focus,.monsterinsights_google_auth_box_next{text-decoration:none;color:#fff}.monsterinsights_google_auth_box_cancel_error:hover,.monsterinsights_google_auth_box_done:hover,.monsterinsights_google_auth_box_next:hover{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;margin-top:10px;color:#fff}#monsterinsights_google_auth_box_footer_left{padding-top:34px}#monsterinsights-google-oauth-window{width:80%;margin-right:10%;margin-left:10%;margin-bottom:10px}#monsterinsights_google_auth_view.monsterinsights_google_auth_reauth{height:650px}.monsterinsights_google_auth_step_data_enterkey_view{width:80%;margin-right:10%;margin-left:10%;height:30px;margin-top:10px}.monsterinsights-google-loading{width:100%;height:100%;background-color:#FFF;color:#000;font-size:30px;padding-top:30px}body.monsterinsights_page .select2-container--open{z-index:300002 !important}.monsterinsights-upsell-box{background-color:#f6fbff;border:1px solid #d6ecff;border-radius:3px;padding:10px 20px}a.monsterinsights-upsell-box-button.button.button-primary{margin-top:20px}.monsterinsights-reports-action-bar-title{font-size:24px;font-weight:700;float:left}#monsterinsights-reports-pages{margin-top:30px}.monsterinsights-grid-border{border:1px solid #e3e9ed;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.monsterinsights-grid-grey-bg{background-color:#f7f7f9;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box}@media (max-width: 600px){.monsterinsights-grid > .monsterinsights-col-1-2{width:100%;margin-top:50px}}.monsterinsights-data-row{width:100%;float:left;box-sizing:border-box;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;color:#7f8591;padding:10px 15px}.monsterinsights-data-row .monsterinsights-col-7-8{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.monsterinsights-reports-box-datalist .monsterinsights-data-row:nth-child(odd){background-color:#f7f7f9}.monsterinsights-reports-box-title{background-color:#FFF;color:#7f8591;font-size:14px;font-weight:700;padding:20px;border-bottom:1px solid #e3e9ed;border-top-left-radius:5px;border-top-right-radius:5px}.monsterinsights-reports-box-datagraph{border:1px solid #e3e9ed;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff;margin:20px;width:auto;padding:20px}.monsterinsights-no-padding-right{padding-right:0}.monsterinsights-datalist-box-title{color:#7f8591;font-size:14px;font-weight:700;margin-bottom:10px}.monsterinsights-reports-action-bar{padding-bottom:40px;margin-top:40px}.monsterinsights-reports-action-bar-actions{float:right}#monsterinsights-chartjs-tooltip{opacity:1;position:absolute;-webkit-transition:all .1s ease;transition:all .1s ease;pointer-events:none;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);border:1px solid #e3e9ed;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#fff;-moz-box-shadow:0 0 20px rgba(97,93,155,.13);-webkit-box-shadow:0 0 20px rgba(97,93,155,.13);box-shadow:0 0 20px rgba(97,93,155,.13);color:#434751;font-size:18px;font-weight:700;padding:8px !important}@font-face{font-family:'monsterinsights';src:url(../fonts/monsterinsights.eot);src:url(../fonts/monsterinsights.eot?#iefix) format("embedded-opentype"),url(../fonts/monsterinsights.woff) format("woff"),url(../fonts/monsterinsights.ttf) format("truetype"),url(../fonts/monsterinsights.svg#monsterinsights) format("svg");font-weight:400;font-style:normal}#monsterinsights-addons [class*='monsterinsights-']:before{display:inline-block;font-family:'monsterinsights';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#monsterinsights-addons .monsterinsights-configuration:before{content:'\0041'}#monsterinsights-addons .monsterinsights-leaf:before{content:'\0042'}#monsterinsights-addons .monsterinsights-lightbox:before{content:'\0044'}#monsterinsights-addons .monsterinsights-misc:before{content:'\0045'}#monsterinsights-addons .monsterinsights-mobile:before{content:'\0046'}#monsterinsights-addons .monsterinsights-pagination:before{content:'\0047'}#monsterinsights-addons .monsterinsights-proofing:before{content:'\0048'}#monsterinsights-addons .monsterinsights-slideshow:before{content:'\0049'}#monsterinsights-addons .monsterinsights-tags:before{content:'\004a'}#monsterinsights-addons .monsterinsights-thumbnails:before{content:'\004b'}#monsterinsights-addons .monsterinsights-video:before{content:'\004c'}#monsterinsights-addons .monsterinsights-watermark:before{content:'\004d'}#monsterinsights-addons .monsterinsights-cloud-download:before{content:'\004e'}#monsterinsights-addons .monsterinsights-toggle-on:before{content:'\004f'}#monsterinsights-addons .monsterinsights-plus-circle:before{content:'\0050'}#monsterinsights-addons .monsterinsights-down-arrow:before{content:'\0051'}#monsterinsights-addons .monsterinsights-list:before{content:'\0052'}#monsterinsights-addons .monsterinsights-pinterest-p:before{content:'\0054'}#monsterinsights-addons .monsterinsights-pencil:before{content:'\0055'}#monsterinsights-addons .monsterinsights-close:before{content:'\0056'}#monsterinsights-addons .monsterinsights-check:before{content:'\0057'}body.monsterinsights_page .monsterinsights-addons-subheading{background-color:#fff;height:45px;margin-left:-20px}body.monsterinsights_page .monsterinsights-addons-subheading h1{font-size:20px;font-weight:400;line-height:45px;margin:0 0 0 20px;padding-left:20px}@media (min-width: 600px) and (max-width: 767px){body.monsterinsights_page .monsterinsights-addons-subheading{height:auto;padding-bottom:20px}}#monsterinsights-addon-heading:after{content:"";display:table;clear:both}#monsterinsights-addon-heading h1{float:left}#monsterinsights-addon-heading form{float:right;margin-right:100px}@media (min-width: 600px) and (max-width: 767px){#monsterinsights-addon-heading h1{float:none}}@media (max-width: 508px){#monsterinsights-addon-heading form{display:none}}@media (max-width: 600px){.monsterinsights-addon .interior{display:none !important}}#monsterinsights-addon-heading form input{border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px;background-color:#fff;color:#666;margin:7px 10px 0 5px;font-size:14px;padding:5px 8px}#monsterinsights-addon-heading form select{margin:-5px 20px 0 0}#monsterinsights-addon-heading form .spinner{float:none;margin:-3px auto auto}@media (min-width: 600px) and (max-width: 767px){#monsterinsights-addon-heading form{float:none;display:table;margin:10px auto 0}}#monsterinsights-addons{padding:0px}#monsterinsights-addons .button,#monsterinsights-addons .button-primary{text-shadow:none;background-color:#f7f7f7;color:#23282d;font-weight:600;border:1px solid #ccc;line-height:inherit;height:inherit;padding:5px 15px;box-shadow:none;cursor:pointer}#monsterinsights-addons .button:hover,#monsterinsights-addons .button-primary:hover{color:#23282d;background-color:#fafafa;border-color:#999}#monsterinsights-addons .monsterinsights-addon-action-button{padding-left:20px;padding-right:20px}#monsterinsights-addons .monsterinsights-addon-action-button .monsterinsights-cloud-download{font-size:19px;float:left;margin-right:8px;color:#8d8f92}#monsterinsights-addons .monsterinsights-addon-action-button .monsterinsights-toggle-on{font-size:19px;float:left;margin-right:8px;margin-top:1px;color:#7cc048}#monsterinsights-addons .monsterinsights-addon-upgrade-button{background-color:#7cc048;color:#fff;float:none !important;margin:0 auto;display:table;line-height:25px}#monsterinsights-addons .monsterinsights-addon-upgrade-button:hover{background-color:#95dc5e;color:#fff;border-color:#95dc5e}#monsterinsights-addons .monsterinsights-addon-action-button.monsterinsights-activate-addon .monsterinsights-toggle-on{color:#e92c21;-moz-transform:scaleX(-1);-o-transform:scaleX(-1);-webkit-transform:scaleX(-1);transform:scaleX(-1);filter:FlipH;-ms-filter:FlipH}#monsterinsights-addons .monsterinsights-addon-title{margin-top:30px}#monsterinsights-addons .monsterinsights-addons-area:after{content:"";display:table;clear:both}#monsterinsights-addons .monsterinsights-addons-area.licensed{margin:20px 0 40px;padding:0 0 20px;border-bottom:1px solid #ddd}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{border:1px solid #ddd;position:relative;background:#fff;border-radius:3px;float:left;margin:0 2% 2% 0;min-height:465px;padding:0;text-align:center;width:32%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon:nth-child(3n){margin-right:0}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon:nth-child(3n+1){clear:both}@media (min-width: 992px) and (max-width: 1199px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{min-height:420px}}@media (min-width: 768px) and (max-width: 991px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{width:100% !important;min-height:525px}}@media (min-width: 600px) and (max-width: 767px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon{width:100% !important;min-height:525px}}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:20px auto;max-width:100%}@media (min-width: 992px) and (max-width: 1199px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}}@media (min-width: 768px) and (max-width: 991px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}}@media (min-width: 600px) and (max-width: 767px){#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-thumb{margin:10px auto 15px}}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{color:#2f2f2f;font-weight:400;padding:0 20px;display:table;margin:0 0 90px}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message{background:#f7f7f7;border-top:1px solid #ddd}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error{position:absolute;bottom:0;float:left;width:100%;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;margin:0;padding:0;text-align:left}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message .interior,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .interior{padding:20px}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message .interior:after,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .interior:after{content:"";display:table;clear:both}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .addon-status span{color:#7cc048}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-active .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-active .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .addon-status span{color:#e82c20}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-inactive .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-inactive .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-active .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-active .addon-status span{color:#7cc048}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-inactive .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-inactive .addon-status span{color:#e82c20}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message.monsterinsights-addon-not-installed .interior.monsterinsights-addon-not-installed .addon-status span,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error.monsterinsights-addon-not-installed .interior.monsterinsights-addon-not-installed .addon-status span{color:#a3a4a5}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.addon-status,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error span.addon-status{float:left;font-weight:700}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message a.button,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error a.button{float:right}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.monsterinsights-spinner,#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error span.monsterinsights-spinner{position:absolute;bottom:15px;right:0}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action{display:inline;float:right}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary{margin:-5px 0 0;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;border-radius:3px}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary:hover{color:#23282d;background-color:#fafafa;border-color:#999}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error{bottom:10px;float:none;left:15px;right:20px;width:auto}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .xinterior{width:100%;margin:0;background:#fff;border-left:4px solid #dc3232;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1)}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error p{padding:10px;margin:5px 10px}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .wrap{margin:0}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .icon32{display:none}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error h2{padding:0}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .form-table th{padding:10px 0;width:30% !important}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .form-table input[type="text"],#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error .monsterinsights-addon .monsterinsights-addon-error .form-table input[type="password"]{width:100% !important}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-error p.submit{padding:0}#monsterinsights-addons .monsterinsights-addons-area .monsterinsights-addon p{color:#2f2f2f;font-size:13px;margin:10px 0 0;text-shadow:0 1px #fff}#monsterinsights-addons .monsterinsights-addons-area #monsterinsights-addons-unlock-more-area{margin:40px auto 20px;padding-bottom:0;border-bottom:0}#monsterinsights-addons-more-area .monsterinsights-addon .interior{padding:15px 20px !important}#monsterinsights-addons-refresh-addons-form{width:100%;max-width:850px;float:left}@media (min-width: 992px) and (max-width: 1199px){#monsterinsights-addons-refresh-addons-form{max-width:450px}}@media (min-width: 768px) and (max-width: 991px){#monsterinsights-addons-refresh-addons-form{max-width:50%}#monsterinsights-addons-refresh-addons-form input.button{display:block}}@media (min-width: 600px) and (max-width: 767px){#monsterinsights-addons-refresh-addons-form{width:100%;float:none}#monsterinsights-addons-refresh-addons-form input.button{display:block}}#monsterinsights-filter-form{float:right}#monsterinsights-filter-form input[type='submit'],#monsterinsights-filter-form select{background-color:#f7f7f7;color:#23282d;border:1px solid #ddd;height:30px;width:120px;margin-top:-2px}#monsterinsights-filter-form input{padding:5px 15px;box-shadow:0;cursor:pointer;background-color:#f7f7f7;color:#23282d}#monsterinsights-filter-form input:hover{color:#23282d;background-color:#fafafa;border-color:#999}#monsterinsights-filter-form .spinner{float:left}@media only screen and (max-width: 1050px){#monsterinsights-addons-area .monsterinsights-addon{width:49%}#monsterinsights-addons-area .monsterinsights-addon:nth-child(2n){margin-right:0}#monsterinsights-addons-area .monsterinsights-addon:nth-child(2n+1){clear:both}#monsterinsights-addons-area .monsterinsights-addon:nth-child(3n){margin-right:2%}#monsterinsights-addons-area .monsterinsights-addon:nth-child(3n+1){clear:none}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{margin-bottom:90px}}@media only screen and (max-width: 782px){#monsterinsights-addons-area .monsterinsights-addon{min-height:auto}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-action .button-primary{margin:-7px 0 0}}@media only screen and (max-width: 600px){#monsterinsights-addons-area .monsterinsights-addon{width:99%}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message{float:left;width:100%}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message span.addon-status{display:block;width:100%;margin:0 0 5px;text-align:center}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message div.monsterinsights-addon-action{clear:both;display:block;width:100%;text-align:center}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-message div.monsterinsights-addon-action .button-primary{clear:both;float:none;margin:0 auto}#monsterinsights-addons-area .monsterinsights-addon .monsterinsights-addon-excerpt{margin-bottom:120px}}
assets/css/font-awesome/font-awesome.css ADDED
@@ -0,0 +1,2199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome
3
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4
+ */
5
+ /* FONT PATH
6
+ * -------------------------- */
7
+ @font-face {
8
+ font-family: 'FontAwesome';
9
+ src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');
10
+ src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');
11
+ font-weight: normal;
12
+ font-style: normal;
13
+ }
14
+ .fa {
15
+ display: inline-block;
16
+ font: normal normal normal 14px/1 FontAwesome;
17
+ font-size: inherit;
18
+ text-rendering: auto;
19
+ -webkit-font-smoothing: antialiased;
20
+ -moz-osx-font-smoothing: grayscale;
21
+ }
22
+ /* makes the font 33% larger relative to the icon container */
23
+ .fa-lg {
24
+ font-size: 1.33333333em;
25
+ line-height: 0.75em;
26
+ vertical-align: -15%;
27
+ }
28
+ .fa-2x {
29
+ font-size: 2em;
30
+ }
31
+ .fa-3x {
32
+ font-size: 3em;
33
+ }
34
+ .fa-4x {
35
+ font-size: 4em;
36
+ }
37
+ .fa-5x {
38
+ font-size: 5em;
39
+ }
40
+ .fa-fw {
41
+ width: 1.28571429em;
42
+ text-align: center;
43
+ }
44
+ .fa-ul {
45
+ padding-left: 0;
46
+ margin-left: 2.14285714em;
47
+ list-style-type: none;
48
+ }
49
+ .fa-ul > li {
50
+ position: relative;
51
+ }
52
+ .fa-li {
53
+ position: absolute;
54
+ left: -2.14285714em;
55
+ width: 2.14285714em;
56
+ top: 0.14285714em;
57
+ text-align: center;
58
+ }
59
+ .fa-li.fa-lg {
60
+ left: -1.85714286em;
61
+ }
62
+ .fa-border {
63
+ padding: .2em .25em .15em;
64
+ border: solid 0.08em #eee;
65
+ border-radius: .1em;
66
+ }
67
+ .fa-pull-left {
68
+ float: left;
69
+ }
70
+ .fa-pull-right {
71
+ float: right;
72
+ }
73
+ .fa.fa-pull-left {
74
+ margin-right: .3em;
75
+ }
76
+ .fa.fa-pull-right {
77
+ margin-left: .3em;
78
+ }
79
+ /* Deprecated as of 4.4.0 */
80
+ .pull-right {
81
+ float: right;
82
+ }
83
+ .pull-left {
84
+ float: left;
85
+ }
86
+ .fa.pull-left {
87
+ margin-right: .3em;
88
+ }
89
+ .fa.pull-right {
90
+ margin-left: .3em;
91
+ }
92
+ .fa-spin {
93
+ -webkit-animation: fa-spin 2s infinite linear;
94
+ animation: fa-spin 2s infinite linear;
95
+ }
96
+ .fa-pulse {
97
+ -webkit-animation: fa-spin 1s infinite steps(8);
98
+ animation: fa-spin 1s infinite steps(8);
99
+ }
100
+ @-webkit-keyframes fa-spin {
101
+ 0% {
102
+ -webkit-transform: rotate(0deg);
103
+ transform: rotate(0deg);
104
+ }
105
+ 100% {
106
+ -webkit-transform: rotate(359deg);
107
+ transform: rotate(359deg);
108
+ }
109
+ }
110
+ @keyframes fa-spin {
111
+ 0% {
112
+ -webkit-transform: rotate(0deg);
113
+ transform: rotate(0deg);
114
+ }
115
+ 100% {
116
+ -webkit-transform: rotate(359deg);
117
+ transform: rotate(359deg);
118
+ }
119
+ }
120
+ .fa-rotate-90 {
121
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
122
+ -webkit-transform: rotate(90deg);
123
+ -ms-transform: rotate(90deg);
124
+ transform: rotate(90deg);
125
+ }
126
+ .fa-rotate-180 {
127
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
128
+ -webkit-transform: rotate(180deg);
129
+ -ms-transform: rotate(180deg);
130
+ transform: rotate(180deg);
131
+ }
132
+ .fa-rotate-270 {
133
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
134
+ -webkit-transform: rotate(270deg);
135
+ -ms-transform: rotate(270deg);
136
+ transform: rotate(270deg);
137
+ }
138
+ .fa-flip-horizontal {
139
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
140
+ -webkit-transform: scale(-1, 1);
141
+ -ms-transform: scale(-1, 1);
142
+ transform: scale(-1, 1);
143
+ }
144
+ .fa-flip-vertical {
145
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
146
+ -webkit-transform: scale(1, -1);
147
+ -ms-transform: scale(1, -1);
148
+ transform: scale(1, -1);
149
+ }
150
+ :root .fa-rotate-90,
151
+ :root .fa-rotate-180,
152
+ :root .fa-rotate-270,
153
+ :root .fa-flip-horizontal,
154
+ :root .fa-flip-vertical {
155
+ filter: none;
156
+ }
157
+ .fa-stack {
158
+ position: relative;
159
+ display: inline-block;
160
+ width: 2em;
161
+ height: 2em;
162
+ line-height: 2em;
163
+ vertical-align: middle;
164
+ }
165
+ .fa-stack-1x,
166
+ .fa-stack-2x {
167
+ position: absolute;
168
+ left: 0;
169
+ width: 100%;
170
+ text-align: center;
171
+ }
172
+ .fa-stack-1x {
173
+ line-height: inherit;
174
+ }
175
+ .fa-stack-2x {
176
+ font-size: 2em;
177
+ }
178
+ .fa-inverse {
179
+ color: #fff;
180
+ }
181
+ /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
182
+ readers do not read off random characters that represent icons */
183
+ .fa-glass:before {
184
+ content: "\f000";
185
+ }
186
+ .fa-music:before {
187
+ content: "\f001";
188
+ }
189
+ .fa-search:before {
190
+ content: "\f002";
191
+ }
192
+ .fa-envelope-o:before {
193
+ content: "\f003";
194
+ }
195
+ .fa-heart:before {
196
+ content: "\f004";
197
+ }
198
+ .fa-star:before {
199
+ content: "\f005";
200
+ }
201
+ .fa-star-o:before {
202
+ content: "\f006";
203
+ }
204
+ .fa-user:before {
205
+ content: "\f007";
206
+ }
207
+ .fa-film:before {
208
+ content: "\f008";
209
+ }
210
+ .fa-th-large:before {
211
+ content: "\f009";
212
+ }
213
+ .fa-th:before {
214
+ content: "\f00a";
215
+ }
216
+ .fa-th-list:before {
217
+ content: "\f00b";
218
+ }
219
+ .fa-check:before {
220
+ content: "\f00c";
221
+ }
222
+ .fa-remove:before,
223
+ .fa-close:before,
224
+ .fa-times:before {
225
+ content: "\f00d";
226
+ }
227
+ .fa-search-plus:before {
228
+ content: "\f00e";
229
+ }
230
+ .fa-search-minus:before {
231
+ content: "\f010";
232
+ }
233
+ .fa-power-off:before {
234
+ content: "\f011";
235
+ }
236
+ .fa-signal:before {
237
+ content: "\f012";
238
+ }
239
+ .fa-gear:before,
240
+ .fa-cog:before {
241
+ content: "\f013";
242
+ }
243
+ .fa-trash-o:before {
244
+ content: "\f014";
245
+ }
246
+ .fa-home:before {
247
+ content: "\f015";
248
+ }
249
+ .fa-file-o:before {
250
+ content: "\f016";
251
+ }
252
+ .fa-clock-o:before {
253
+ content: "\f017";
254
+ }
255
+ .fa-road:before {
256
+ content: "\f018";
257
+ }
258
+ .fa-download:before {
259
+ content: "\f019";
260
+ }
261
+ .fa-arrow-circle-o-down:before {
262
+ content: "\f01a";
263
+ }
264
+ .fa-arrow-circle-o-up:before {
265
+ content: "\f01b";
266
+ }
267
+ .fa-inbox:before {
268
+ content: "\f01c";
269
+ }
270
+ .fa-play-circle-o:before {
271
+ content: "\f01d";
272
+ }
273
+ .fa-rotate-right:before,
274
+ .fa-repeat:before {
275
+ content: "\f01e";
276
+ }
277
+ .fa-refresh:before {
278
+ content: "\f021";
279
+ }
280
+ .fa-list-alt:before {
281
+ content: "\f022";
282
+ }
283
+ .fa-lock:before {
284
+ content: "\f023";
285
+ }
286
+ .fa-flag:before {
287
+ content: "\f024";
288
+ }
289
+ .fa-headphones:before {
290
+ content: "\f025";
291
+ }
292
+ .fa-volume-off:before {
293
+ content: "\f026";
294
+ }
295
+ .fa-volume-down:before {
296
+ content: "\f027";
297
+ }
298
+ .fa-volume-up:before {
299
+ content: "\f028";
300
+ }
301
+ .fa-qrcode:before {
302
+ content: "\f029";
303
+ }
304
+ .fa-barcode:before {
305
+ content: "\f02a";
306
+ }
307
+ .fa-tag:before {
308
+ content: "\f02b";
309
+ }
310
+ .fa-tags:before {
311
+ content: "\f02c";
312
+ }
313
+ .fa-book:before {
314
+ content: "\f02d";
315
+ }
316
+ .fa-bookmark:before {
317
+ content: "\f02e";
318
+ }
319
+ .fa-print:before {
320
+ content: "\f02f";
321
+ }
322
+ .fa-camera:before {
323
+ content: "\f030";
324
+ }
325
+ .fa-font:before {
326
+ content: "\f031";
327
+ }
328
+ .fa-bold:before {
329
+ content: "\f032";
330
+ }
331
+ .fa-italic:before {
332
+ content: "\f033";
333
+ }
334
+ .fa-text-height:before {
335
+ content: "\f034";
336
+ }
337
+ .fa-text-width:before {
338
+ content: "\f035";
339
+ }
340
+ .fa-align-left:before {
341
+ content: "\f036";
342
+ }
343
+ .fa-align-center:before {
344
+ content: "\f037";
345
+ }
346
+ .fa-align-right:before {
347
+ content: "\f038";
348
+ }
349
+ .fa-align-justify:before {
350
+ content: "\f039";
351
+ }
352
+ .fa-list:before {
353
+ content: "\f03a";
354
+ }
355
+ .fa-dedent:before,
356
+ .fa-outdent:before {
357
+ content: "\f03b";
358
+ }
359
+ .fa-indent:before {
360
+ content: "\f03c";
361
+ }
362
+ .fa-video-camera:before {
363
+ content: "\f03d";
364
+ }
365
+ .fa-photo:before,
366
+ .fa-image:before,
367
+ .fa-picture-o:before {
368
+ content: "\f03e";
369
+ }
370
+ .fa-pencil:before {
371
+ content: "\f040";
372
+ }
373
+ .fa-map-marker:before {
374
+ content: "\f041";
375
+ }
376
+ .fa-adjust:before {
377
+ content: "\f042";
378
+ }
379
+ .fa-tint:before {
380
+ content: "\f043";
381
+ }
382
+ .fa-edit:before,
383
+ .fa-pencil-square-o:before {
384
+ content: "\f044";
385
+ }
386
+ .fa-share-square-o:before {
387
+ content: "\f045";
388
+ }
389
+ .fa-check-square-o:before {
390
+ content: "\f046";
391
+ }
392
+ .fa-arrows:before {
393
+ content: "\f047";
394
+ }
395
+ .fa-step-backward:before {
396
+ content: "\f048";
397
+ }
398
+ .fa-fast-backward:before {
399
+ content: "\f049";
400
+ }
401
+ .fa-backward:before {
402
+ content: "\f04a";
403
+ }
404
+ .fa-play:before {
405
+ content: "\f04b";
406
+ }
407
+ .fa-pause:before {
408
+ content: "\f04c";
409
+ }
410
+ .fa-stop:before {
411
+ content: "\f04d";
412
+ }
413
+ .fa-forward:before {
414
+ content: "\f04e";
415
+ }
416
+ .fa-fast-forward:before {
417
+ content: "\f050";
418
+ }
419
+ .fa-step-forward:before {
420
+ content: "\f051";
421
+ }
422
+ .fa-eject:before {
423
+ content: "\f052";
424
+ }
425
+ .fa-chevron-left:before {
426
+ content: "\f053";
427
+ }
428
+ .fa-chevron-right:before {
429
+ content: "\f054";
430
+ }
431
+ .fa-plus-circle:before {
432
+ content: "\f055";
433
+ }
434
+ .fa-minus-circle:before {
435
+ content: "\f056";
436
+ }
437
+ .fa-times-circle:before {
438
+ content: "\f057";
439
+ }
440
+ .fa-check-circle:before {
441
+ content: "\f058";
442
+ }
443
+ .fa-question-circle:before {
444
+ content: "\f059";
445
+ }
446
+ .fa-info-circle:before {
447
+ content: "\f05a";
448
+ }
449
+ .fa-crosshairs:before {
450
+ content: "\f05b";
451
+ }
452
+ .fa-times-circle-o:before {
453
+ content: "\f05c";
454
+ }
455
+ .fa-check-circle-o:before {
456
+ content: "\f05d";
457
+ }
458
+ .fa-ban:before {
459
+ content: "\f05e";
460
+ }
461
+ .fa-arrow-left:before {
462
+ content: "\f060";
463
+ }
464
+ .fa-arrow-right:before {
465
+ content: "\f061";
466
+ }
467
+ .fa-arrow-up:before {
468
+ content: "\f062";
469
+ }
470
+ .fa-arrow-down:before {
471
+ content: "\f063";
472
+ }
473
+ .fa-mail-forward:before,
474
+ .fa-share:before {
475
+ content: "\f064";
476
+ }
477
+ .fa-expand:before {
478
+ content: "\f065";
479
+ }
480
+ .fa-compress:before {
481
+ content: "\f066";
482
+ }
483
+ .fa-plus:before {
484
+ content: "\f067";
485
+ }
486
+ .fa-minus:before {
487
+ content: "\f068";
488
+ }
489
+ .fa-asterisk:before {
490
+ content: "\f069";
491
+ }
492
+ .fa-exclamation-circle:before {
493
+ content: "\f06a";
494
+ }
495
+ .fa-gift:before {
496
+ content: "\f06b";
497
+ }
498
+ .fa-leaf:before {
499
+ content: "\f06c";
500
+ }
501
+ .fa-fire:before {
502
+ content: "\f06d";
503
+ }
504
+ .fa-eye:before {
505
+ content: "\f06e";
506
+ }
507
+ .fa-eye-slash:before {
508
+ content: "\f070";
509
+ }
510
+ .fa-warning:before,
511
+ .fa-exclamation-triangle:before {
512
+ content: "\f071";
513
+ }
514
+ .fa-plane:before {
515
+ content: "\f072";
516
+ }
517
+ .fa-calendar:before {
518
+ content: "\f073";
519
+ }
520
+ .fa-random:before {
521
+ content: "\f074";
522
+ }
523
+ .fa-comment:before {
524
+ content: "\f075";
525
+ }
526
+ .fa-magnet:before {
527
+ content: "\f076";
528
+ }
529
+ .fa-chevron-up:before {
530
+ content: "\f077";
531
+ }
532
+ .fa-chevron-down:before {
533
+ content: "\f078";
534
+ }
535
+ .fa-retweet:before {
536
+ content: "\f079";
537
+ }
538
+ .fa-shopping-cart:before {
539
+ content: "\f07a";
540
+ }
541
+ .fa-folder:before {
542
+ content: "\f07b";
543
+ }
544
+ .fa-folder-open:before {
545
+ content: "\f07c";
546
+ }
547
+ .fa-arrows-v:before {
548
+ content: "\f07d";
549
+ }
550
+ .fa-arrows-h:before {
551
+ content: "\f07e";
552
+ }
553
+ .fa-bar-chart-o:before,
554
+ .fa-bar-chart:before {
555
+ content: "\f080";
556
+ }
557
+ .fa-twitter-square:before {
558
+ content: "\f081";
559
+ }
560
+ .fa-facebook-square:before {
561
+ content: "\f082";
562
+ }
563
+ .fa-camera-retro:before {
564
+ content: "\f083";
565
+ }
566
+ .fa-key:before {
567
+ content: "\f084";
568
+ }
569
+ .fa-gears:before,
570
+ .fa-cogs:before {
571
+ content: "\f085";
572
+ }
573
+ .fa-comments:before {
574
+ content: "\f086";
575
+ }
576
+ .fa-thumbs-o-up:before {
577
+ content: "\f087";
578
+ }
579
+ .fa-thumbs-o-down:before {
580
+ content: "\f088";
581
+ }
582
+ .fa-star-half:before {
583
+ content: "\f089";
584
+ }
585
+ .fa-heart-o:before {
586
+ content: "\f08a";
587
+ }
588
+ .fa-sign-out:before {
589
+ content: "\f08b";
590
+ }
591
+ .fa-linkedin-square:before {
592
+ content: "\f08c";
593
+ }
594
+ .fa-thumb-tack:before {
595
+ content: "\f08d";
596
+ }
597
+ .fa-external-link:before {
598
+ content: "\f08e";
599
+ }
600
+ .fa-sign-in:before {
601
+ content: "\f090";
602
+ }
603
+ .fa-trophy:before {
604
+ content: "\f091";
605
+ }
606
+ .fa-github-square:before {
607
+ content: "\f092";
608
+ }
609
+ .fa-upload:before {
610
+ content: "\f093";
611
+ }
612
+ .fa-lemon-o:before {
613
+ content: "\f094";
614
+ }
615
+ .fa-phone:before {
616
+ content: "\f095";
617
+ }
618
+ .fa-square-o:before {
619
+ content: "\f096";
620
+ }
621
+ .fa-bookmark-o:before {
622
+ content: "\f097";
623
+ }
624
+ .fa-phone-square:before {
625
+ content: "\f098";
626
+ }
627
+ .fa-twitter:before {
628
+ content: "\f099";
629
+ }
630
+ .fa-facebook-f:before,
631
+ .fa-facebook:before {
632
+ content: "\f09a";
633
+ }
634
+ .fa-github:before {
635
+ content: "\f09b";
636
+ }
637
+ .fa-unlock:before {
638
+ content: "\f09c";
639
+ }
640
+ .fa-credit-card:before {
641
+ content: "\f09d";
642
+ }
643
+ .fa-feed:before,
644
+ .fa-rss:before {
645
+ content: "\f09e";
646
+ }
647
+ .fa-hdd-o:before {
648
+ content: "\f0a0";
649
+ }
650
+ .fa-bullhorn:before {
651
+ content: "\f0a1";
652
+ }
653
+ .fa-bell:before {
654
+ content: "\f0f3";
655
+ }
656
+ .fa-certificate:before {
657
+ content: "\f0a3";
658
+ }
659
+ .fa-hand-o-right:before {
660
+ content: "\f0a4";
661
+ }
662
+ .fa-hand-o-left:before {
663
+ content: "\f0a5";
664
+ }
665
+ .fa-hand-o-up:before {
666
+ content: "\f0a6";
667
+ }
668
+ .fa-hand-o-down:before {
669
+ content: "\f0a7";
670
+ }
671
+ .fa-arrow-circle-left:before {
672
+ content: "\f0a8";
673
+ }
674
+ .fa-arrow-circle-right:before {
675
+ content: "\f0a9";
676
+ }
677
+ .fa-arrow-circle-up:before {
678
+ content: "\f0aa";
679
+ }
680
+ .fa-arrow-circle-down:before {
681
+ content: "\f0ab";
682
+ }
683
+ .fa-globe:before {
684
+ content: "\f0ac";
685
+ }
686
+ .fa-wrench:before {
687
+ content: "\f0ad";
688
+ }
689
+ .fa-tasks:before {
690
+ content: "\f0ae";
691
+ }
692
+ .fa-filter:before {
693
+ content: "\f0b0";
694
+ }
695
+ .fa-briefcase:before {
696
+ content: "\f0b1";
697
+ }
698
+ .fa-arrows-alt:before {
699
+ content: "\f0b2";
700
+ }
701
+ .fa-group:before,
702
+ .fa-users:before {
703
+ content: "\f0c0";
704
+ }
705
+ .fa-chain:before,
706
+ .fa-link:before {
707
+ content: "\f0c1";
708
+ }
709
+ .fa-cloud:before {
710
+ content: "\f0c2";
711
+ }
712
+ .fa-flask:before {
713
+ content: "\f0c3";
714
+ }
715
+ .fa-cut:before,
716
+ .fa-scissors:before {
717
+ content: "\f0c4";
718
+ }
719
+ .fa-copy:before,
720
+ .fa-files-o:before {
721
+ content: "\f0c5";
722
+ }
723
+ .fa-paperclip:before {
724
+ content: "\f0c6";
725
+ }
726
+ .fa-save:before,
727
+ .fa-floppy-o:before {
728
+ content: "\f0c7";
729
+ }
730
+ .fa-square:before {
731
+ content: "\f0c8";
732
+ }
733
+ .fa-navicon:before,
734
+ .fa-reorder:before,
735
+ .fa-bars:before {
736
+ content: "\f0c9";
737
+ }
738
+ .fa-list-ul:before {
739
+ content: "\f0ca";
740
+ }
741
+ .fa-list-ol:before {
742
+ content: "\f0cb";
743
+ }
744
+ .fa-strikethrough:before {
745
+ content: "\f0cc";
746
+ }
747
+ .fa-underline:before {
748
+ content: "\f0cd";
749
+ }
750
+ .fa-table:before {
751
+ content: "\f0ce";
752
+ }
753
+ .fa-magic:before {
754
+ content: "\f0d0";
755
+ }
756
+ .fa-truck:before {
757
+ content: "\f0d1";
758
+ }
759
+ .fa-pinterest:before {
760
+ content: "\f0d2";
761
+ }
762
+ .fa-pinterest-square:before {
763
+ content: "\f0d3";
764
+ }
765
+ .fa-google-plus-square:before {
766
+ content: "\f0d4";
767
+ }
768
+ .fa-google-plus:before {
769
+ content: "\f0d5";
770
+ }
771
+ .fa-money:before {
772
+ content: "\f0d6";
773
+ }
774
+ .fa-caret-down:before {
775
+ content: "\f0d7";
776
+ }
777
+ .fa-caret-up:before {
778
+ content: "\f0d8";
779
+ }
780
+ .fa-caret-left:before {
781
+ content: "\f0d9";
782
+ }
783
+ .fa-caret-right:before {
784
+ content: "\f0da";
785
+ }
786
+ .fa-columns:before {
787
+ content: "\f0db";
788
+ }
789
+ .fa-unsorted:before,
790
+ .fa-sort:before {
791
+ content: "\f0dc";
792
+ }
793
+ .fa-sort-down:before,
794
+ .fa-sort-desc:before {
795
+ content: "\f0dd";
796
+ }
797
+ .fa-sort-up:before,
798
+ .fa-sort-asc:before {
799
+ content: "\f0de";
800
+ }
801
+ .fa-envelope:before {
802
+ content: "\f0e0";
803
+ }
804
+ .fa-linkedin:before {
805
+ content: "\f0e1";
806
+ }
807
+ .fa-rotate-left:before,
808
+ .fa-undo:before {
809
+ content: "\f0e2";
810
+ }
811
+ .fa-legal:before,
812
+ .fa-gavel:before {
813
+ content: "\f0e3";
814
+ }
815
+ .fa-dashboard:before,
816
+ .fa-tachometer:before {
817
+ content: "\f0e4";
818
+ }
819
+ .fa-comment-o:before {
820
+ content: "\f0e5";
821
+ }
822
+ .fa-comments-o:before {
823
+ content: "\f0e6";
824
+ }
825
+ .fa-flash:before,
826
+ .fa-bolt:before {
827
+ content: "\f0e7";
828
+ }
829
+ .fa-sitemap:before {
830
+ content: "\f0e8";
831
+ }
832
+ .fa-umbrella:before {
833
+ content: "\f0e9";
834
+ }
835
+ .fa-paste:before,
836
+ .fa-clipboard:before {
837
+ content: "\f0ea";
838
+ }
839
+ .fa-lightbulb-o:before {
840
+ content: "\f0eb";
841
+ }
842
+ .fa-exchange:before {
843
+ content: "\f0ec";
844
+ }
845
+ .fa-cloud-download:before {
846
+ content: "\f0ed";
847
+ }
848
+ .fa-cloud-upload:before {
849
+ content: "\f0ee";
850
+ }
851
+ .fa-user-md:before {
852
+ content: "\f0f0";
853
+ }
854
+ .fa-stethoscope:before {
855
+ content: "\f0f1";
856
+ }
857
+ .fa-suitcase:before {
858
+ content: "\f0f2";
859
+ }
860
+ .fa-bell-o:before {
861
+ content: "\f0a2";
862
+ }
863
+ .fa-coffee:before {
864
+ content: "\f0f4";
865
+ }
866
+ .fa-cutlery:before {
867
+ content: "\f0f5";
868
+ }
869
+ .fa-file-text-o:before {
870
+ content: "\f0f6";
871
+ }
872
+ .fa-building-o:before {
873
+ content: "\f0f7";
874
+ }
875
+ .fa-hospital-o:before {
876
+ content: "\f0f8";
877
+ }
878
+ .fa-ambulance:before {
879
+ content: "\f0f9";
880
+ }
881
+ .fa-medkit:before {
882
+ content: "\f0fa";
883
+ }
884
+ .fa-fighter-jet:before {
885
+ content: "\f0fb";
886
+ }
887
+ .fa-beer:before {
888
+ content: "\f0fc";
889
+ }
890
+ .fa-h-square:before {
891
+ content: "\f0fd";
892
+ }
893
+ .fa-plus-square:before {
894
+ content: "\f0fe";
895
+ }
896
+ .fa-angle-double-left:before {
897
+ content: "\f100";
898
+ }
899
+ .fa-angle-double-right:before {
900
+ content: "\f101";
901
+ }
902
+ .fa-angle-double-up:before {
903
+ content: "\f102";
904
+ }
905
+ .fa-angle-double-down:before {
906
+ content: "\f103";
907
+ }
908
+ .fa-angle-left:before {
909
+ content: "\f104";
910
+ }
911
+ .fa-angle-right:before {
912
+ content: "\f105";
913
+ }
914
+ .fa-angle-up:before {
915
+ content: "\f106";
916
+ }
917
+ .fa-angle-down:before {
918
+ content: "\f107";
919
+ }
920
+ .fa-desktop:before {
921
+ content: "\f108";
922
+ }
923
+ .fa-laptop:before {
924
+ content: "\f109";
925
+ }
926
+ .fa-tablet:before {
927
+ content: "\f10a";
928
+ }
929
+ .fa-mobile-phone:before,
930
+ .fa-mobile:before {
931
+ content: "\f10b";
932
+ }
933
+ .fa-circle-o:before {
934
+ content: "\f10c";
935
+ }
936
+ .fa-quote-left:before {
937
+ content: "\f10d";
938
+ }
939
+ .fa-quote-right:before {
940
+ content: "\f10e";
941
+ }
942
+ .fa-spinner:before {
943
+ content: "\f110";
944
+ }
945
+ .fa-circle:before {
946
+ content: "\f111";
947
+ }
948
+ .fa-mail-reply:before,
949
+ .fa-reply:before {
950
+ content: "\f112";
951
+ }
952
+ .fa-github-alt:before {
953
+ content: "\f113";
954
+ }
955
+ .fa-folder-o:before {
956
+ content: "\f114";
957
+ }
958
+ .fa-folder-open-o:before {
959
+ content: "\f115";
960
+ }
961
+ .fa-smile-o:before {
962
+ content: "\f118";
963
+ }
964
+ .fa-frown-o:before {
965
+ content: "\f119";
966
+ }
967
+ .fa-meh-o:before {
968
+ content: "\f11a";
969
+ }
970
+ .fa-gamepad:before {
971
+ content: "\f11b";
972
+ }
973
+ .fa-keyboard-o:before {
974
+ content: "\f11c";
975
+ }
976
+ .fa-flag-o:before {
977
+ content: "\f11d";
978
+ }
979
+ .fa-flag-checkered:before {
980
+ content: "\f11e";
981
+ }
982
+ .fa-terminal:before {
983
+ content: "\f120";
984
+ }
985
+ .fa-code:before {
986
+ content: "\f121";
987
+ }
988
+ .fa-mail-reply-all:before,
989
+ .fa-reply-all:before {
990
+ content: "\f122";
991
+ }
992
+ .fa-star-half-empty:before,
993
+ .fa-star-half-full:before,
994
+ .fa-star-half-o:before {
995
+ content: "\f123";
996
+ }
997
+ .fa-location-arrow:before {
998
+ content: "\f124";
999
+ }
1000
+ .fa-crop:before {
1001
+ content: "\f125";
1002
+ }
1003
+ .fa-code-fork:before {
1004
+ content: "\f126";
1005
+ }
1006
+ .fa-unlink:before,
1007
+ .fa-chain-broken:before {
1008
+ content: "\f127";
1009
+ }
1010
+ .fa-question:before {
1011
+ content: "\f128";
1012
+ }
1013
+ .fa-info:before {
1014
+ content: "\f129";
1015
+ }
1016
+ .fa-exclamation:before {
1017
+ content: "\f12a";
1018
+ }
1019
+ .fa-superscript:before {
1020
+ content: "\f12b";
1021
+ }
1022
+ .fa-subscript:before {
1023
+ content: "\f12c";
1024
+ }
1025
+ .fa-eraser:before {
1026
+ content: "\f12d";
1027
+ }
1028
+ .fa-puzzle-piece:before {
1029
+ content: "\f12e";
1030
+ }
1031
+ .fa-microphone:before {
1032
+ content: "\f130";
1033
+ }
1034
+ .fa-microphone-slash:before {
1035
+ content: "\f131";
1036
+ }
1037
+ .fa-shield:before {
1038
+ content: "\f132";
1039
+ }
1040
+ .fa-calendar-o:before {
1041
+ content: "\f133";
1042
+ }
1043
+ .fa-fire-extinguisher:before {
1044
+ content: "\f134";
1045
+ }
1046
+ .fa-rocket:before {
1047
+ content: "\f135";
1048
+ }
1049
+ .fa-maxcdn:before {
1050
+ content: "\f136";
1051
+ }
1052
+ .fa-chevron-circle-left:before {
1053
+ content: "\f137";
1054
+ }
1055
+ .fa-chevron-circle-right:before {
1056
+ content: "\f138";
1057
+ }
1058
+ .fa-chevron-circle-up:before {
1059
+ content: "\f139";
1060
+ }
1061
+ .fa-chevron-circle-down:before {
1062
+ content: "\f13a";
1063
+ }
1064
+ .fa-html5:before {
1065
+ content: "\f13b";
1066
+ }
1067
+ .fa-css3:before {
1068
+ content: "\f13c";
1069
+ }
1070
+ .fa-anchor:before {
1071
+ content: "\f13d";
1072
+ }
1073
+ .fa-unlock-alt:before {
1074
+ content: "\f13e";
1075
+ }
1076
+ .fa-bullseye:before {
1077
+ content: "\f140";
1078
+ }
1079
+ .fa-ellipsis-h:before {
1080
+ content: "\f141";
1081
+ }
1082
+ .fa-ellipsis-v:before {
1083
+ content: "\f142";
1084
+ }
1085
+ .fa-rss-square:before {
1086
+ content: "\f143";
1087
+ }
1088
+ .fa-play-circle:before {
1089
+ content: "\f144";
1090
+ }
1091
+ .fa-ticket:before {
1092
+ content: "\f145";
1093
+ }
1094
+ .fa-minus-square:before {
1095
+ content: "\f146";
1096
+ }
1097
+ .fa-minus-square-o:before {
1098
+ content: "\f147";
1099
+ }
1100
+ .fa-level-up:before {
1101
+ content: "\f148";
1102
+ }
1103
+ .fa-level-down:before {
1104
+ content: "\f149";
1105
+ }
1106
+ .fa-check-square:before {
1107
+ content: "\f14a";
1108
+ }
1109
+ .fa-pencil-square:before {
1110
+ content: "\f14b";
1111
+ }
1112
+ .fa-external-link-square:before {
1113
+ content: "\f14c";
1114
+ }
1115
+ .fa-share-square:before {
1116
+ content: "\f14d";
1117
+ }
1118
+ .fa-compass:before {
1119
+ content: "\f14e";
1120
+ }
1121
+ .fa-toggle-down:before,
1122
+ .fa-caret-square-o-down:before {
1123
+ content: "\f150";
1124
+ }
1125
+ .fa-toggle-up:before,
1126
+ .fa-caret-square-o-up:before {
1127
+ content: "\f151";
1128
+ }
1129
+ .fa-toggle-right:before,
1130
+ .fa-caret-square-o-right:before {
1131
+ content: "\f152";
1132
+ }
1133
+ .fa-euro:before,
1134
+ .fa-eur:before {
1135
+ content: "\f153";
1136
+ }
1137
+ .fa-gbp:before {
1138
+ content: "\f154";
1139
+ }
1140
+ .fa-dollar:before,
1141
+ .fa-usd:before {
1142
+ content: "\f155";
1143
+ }
1144
+ .fa-rupee:before,
1145
+ .fa-inr:before {
1146
+ content: "\f156";
1147
+ }
1148
+ .fa-cny:before,
1149
+ .fa-rmb:before,
1150
+ .fa-yen:before,
1151
+ .fa-jpy:before {
1152
+ content: "\f157";
1153
+ }
1154
+ .fa-ruble:before,
1155
+ .fa-rouble:before,
1156
+ .fa-rub:before {
1157
+ content: "\f158";
1158
+ }
1159
+ .fa-won:before,
1160
+ .fa-krw:before {
1161
+ content: "\f159";
1162
+ }
1163
+ .fa-bitcoin:before,
1164
+ .fa-btc:before {
1165
+ content: "\f15a";
1166
+ }
1167
+ .fa-file:before {
1168
+ content: "\f15b";
1169
+ }
1170
+ .fa-file-text:before {
1171
+ content: "\f15c";
1172
+ }
1173
+ .fa-sort-alpha-asc:before {
1174
+ content: "\f15d";
1175
+ }
1176
+ .fa-sort-alpha-desc:before {
1177
+ content: "\f15e";
1178
+ }
1179
+ .fa-sort-amount-asc:before {
1180
+ content: "\f160";
1181
+ }
1182
+ .fa-sort-amount-desc:before {
1183
+ content: "\f161";
1184
+ }
1185
+ .fa-sort-numeric-asc:before {
1186
+ content: "\f162";
1187
+ }
1188
+ .fa-sort-numeric-desc:before {
1189
+ content: "\f163";
1190
+ }
1191
+ .fa-thumbs-up:before {
1192
+ content: "\f164";
1193
+ }
1194
+ .fa-thumbs-down:before {
1195
+ content: "\f165";
1196
+ }
1197
+ .fa-youtube-square:before {
1198
+ content: "\f166";
1199
+ }
1200
+ .fa-youtube:before {
1201
+ content: "\f167";
1202
+ }
1203
+ .fa-xing:before {
1204
+ content: "\f168";
1205
+ }
1206
+ .fa-xing-square:before {
1207
+ content: "\f169";
1208
+ }
1209
+ .fa-youtube-play:before {
1210
+ content: "\f16a";
1211
+ }
1212
+ .fa-dropbox:before {
1213
+ content: "\f16b";
1214
+ }
1215
+ .fa-stack-overflow:before {
1216
+ content: "\f16c";
1217
+ }
1218
+ .fa-instagram:before {
1219
+ content: "\f16d";
1220
+ }
1221
+ .fa-flickr:before {
1222
+ content: "\f16e";
1223
+ }
1224
+ .fa-adn:before {
1225
+ content: "\f170";
1226
+ }
1227
+ .fa-bitbucket:before {
1228
+ content: "\f171";
1229
+ }
1230
+ .fa-bitbucket-square:before {
1231
+ content: "\f172";
1232
+ }
1233
+ .fa-tumblr:before {
1234
+ content: "\f173";
1235
+ }
1236
+ .fa-tumblr-square:before {
1237
+ content: "\f174";
1238
+ }
1239
+ .fa-long-arrow-down:before {
1240
+ content: "\f175";
1241
+ }
1242
+ .fa-long-arrow-up:before {
1243
+ content: "\f176";
1244
+ }
1245
+ .fa-long-arrow-left:before {
1246
+ content: "\f177";
1247
+ }
1248
+ .fa-long-arrow-right:before {
1249
+ content: "\f178";
1250
+ }
1251
+ .fa-apple:before {
1252
+ content: "\f179";
1253
+ }
1254
+ .fa-windows:before {
1255
+ content: "\f17a";
1256
+ }
1257
+ .fa-android:before {
1258
+ content: "\f17b";
1259
+ }
1260
+ .fa-linux:before {
1261
+ content: "\f17c";
1262
+ }
1263
+ .fa-dribbble:before {
1264
+ content: "\f17d";
1265
+ }
1266
+ .fa-skype:before {
1267
+ content: "\f17e";
1268
+ }
1269
+ .fa-foursquare:before {
1270
+ content: "\f180";
1271
+ }
1272
+ .fa-trello:before {
1273
+ content: "\f181";
1274
+ }
1275
+ .fa-female:before {
1276
+ content: "\f182";
1277
+ }
1278
+ .fa-male:before {
1279
+ content: "\f183";
1280
+ }
1281
+ .fa-gittip:before,
1282
+ .fa-gratipay:before {
1283
+ content: "\f184";
1284
+ }
1285
+ .fa-sun-o:before {
1286
+ content: "\f185";
1287
+ }
1288
+ .fa-moon-o:before {
1289
+ content: "\f186";
1290
+ }
1291
+ .fa-archive:before {
1292
+ content: "\f187";
1293
+ }
1294
+ .fa-bug:before {
1295
+ content: "\f188";
1296
+ }
1297
+ .fa-vk:before {
1298
+ content: "\f189";
1299
+ }
1300
+ .fa-weibo:before {
1301
+ content: "\f18a";
1302
+ }
1303
+ .fa-renren:before {
1304
+ content: "\f18b";
1305
+ }
1306
+ .fa-pagelines:before {
1307
+ content: "\f18c";
1308
+ }
1309
+ .fa-stack-exchange:before {
1310
+ content: "\f18d";
1311
+ }
1312
+ .fa-arrow-circle-o-right:before {
1313
+ content: "\f18e";
1314
+ }
1315
+ .fa-arrow-circle-o-left:before {
1316
+ content: "\f190";
1317
+ }
1318
+ .fa-toggle-left:before,
1319
+ .fa-caret-square-o-left:before {
1320
+ content: "\f191";
1321
+ }
1322
+ .fa-dot-circle-o:before {
1323
+ content: "\f192";
1324
+ }
1325
+ .fa-wheelchair:before {
1326
+ content: "\f193";
1327
+ }
1328
+ .fa-vimeo-square:before {
1329
+ content: "\f194";
1330
+ }
1331
+ .fa-turkish-lira:before,
1332
+ .fa-try:before {
1333
+ content: "\f195";
1334
+ }
1335
+ .fa-plus-square-o:before {
1336
+ content: "\f196";
1337
+ }
1338
+ .fa-space-shuttle:before {
1339
+ content: "\f197";
1340
+ }
1341
+ .fa-slack:before {
1342
+ content: "\f198";
1343
+ }
1344
+ .fa-envelope-square:before {
1345
+ content: "\f199";
1346
+ }
1347
+ .fa-wordpress:before {
1348
+ content: "\f19a";
1349
+ }
1350
+ .fa-openid:before {
1351
+ content: "\f19b";
1352
+ }
1353
+ .fa-institution:before,
1354
+ .fa-bank:before,
1355
+ .fa-university:before {
1356
+ content: "\f19c";
1357
+ }
1358
+ .fa-mortar-board:before,
1359
+ .fa-graduation-cap:before {
1360
+ content: "\f19d";
1361
+ }
1362
+ .fa-yahoo:before {
1363
+ content: "\f19e";
1364
+ }
1365
+ .fa-google:before {
1366
+ content: "\f1a0";
1367
+ }
1368
+ .fa-reddit:before {
1369
+ content: "\f1a1";
1370
+ }
1371
+ .fa-reddit-square:before {
1372
+ content: "\f1a2";
1373
+ }
1374
+ .fa-stumbleupon-circle:before {
1375
+ content: "\f1a3";
1376
+ }
1377
+ .fa-stumbleupon:before {
1378
+ content: "\f1a4";
1379
+ }
1380
+ .fa-delicious:before {
1381
+ content: "\f1a5";
1382
+ }
1383
+ .fa-digg:before {
1384
+ content: "\f1a6";
1385
+ }
1386
+ .fa-pied-piper-pp:before {
1387
+ content: "\f1a7";
1388
+ }
1389
+ .fa-pied-piper-alt:before {
1390
+ content: "\f1a8";
1391
+ }
1392
+ .fa-drupal:before {
1393
+ content: "\f1a9";
1394
+ }
1395
+ .fa-joomla:before {
1396
+ content: "\f1aa";
1397
+ }
1398
+ .fa-language:before {
1399
+ content: "\f1ab";
1400
+ }
1401
+ .fa-fax:before {
1402
+ content: "\f1ac";
1403
+ }
1404
+ .fa-building:before {
1405
+ content: "\f1ad";
1406
+ }
1407
+ .fa-child:before {
1408
+ content: "\f1ae";
1409
+ }
1410
+ .fa-paw:before {
1411
+ content: "\f1b0";
1412
+ }
1413
+ .fa-spoon:before {
1414
+ content: "\f1b1";
1415
+ }
1416
+ .fa-cube:before {
1417
+ content: "\f1b2";
1418
+ }
1419
+ .fa-cubes:before {
1420
+ content: "\f1b3";
1421
+ }
1422
+ .fa-behance:before {
1423
+ content: "\f1b4";
1424
+ }
1425
+ .fa-behance-square:before {
1426
+ content: "\f1b5";
1427
+ }
1428
+ .fa-steam:before {
1429
+ content: "\f1b6";
1430
+ }
1431
+ .fa-steam-square:before {
1432
+ content: "\f1b7";
1433
+ }
1434
+ .fa-recycle:before {
1435
+ content: "\f1b8";
1436
+ }
1437
+ .fa-automobile:before,
1438
+ .fa-car:before {
1439
+ content: "\f1b9";
1440
+ }
1441
+ .fa-cab:before,
1442
+ .fa-taxi:before {
1443
+ content: "\f1ba";
1444
+ }
1445
+ .fa-tree:before {
1446
+ content: "\f1bb";
1447
+ }
1448
+ .fa-spotify:before {
1449
+ content: "\f1bc";
1450
+ }
1451
+ .fa-deviantart:before {
1452
+ content: "\f1bd";
1453
+ }
1454
+ .fa-soundcloud:before {
1455
+ content: "\f1be";
1456
+ }
1457
+ .fa-database:before {
1458
+ content: "\f1c0";
1459
+ }
1460
+ .fa-file-pdf-o:before {
1461
+ content: "\f1c1";
1462
+ }
1463
+ .fa-file-word-o:before {
1464
+ content: "\f1c2";
1465
+ }
1466
+ .fa-file-excel-o:before {
1467
+ content: "\f1c3";
1468
+ }
1469
+ .fa-file-powerpoint-o:before {
1470
+ content: "\f1c4";
1471
+ }
1472
+ .fa-file-photo-o:before,
1473
+ .fa-file-picture-o:before,
1474
+ .fa-file-image-o:before {
1475
+ content: "\f1c5";
1476
+ }
1477
+ .fa-file-zip-o:before,
1478
+ .fa-file-archive-o:before {
1479
+ content: "\f1c6";
1480
+ }
1481
+ .fa-file-sound-o:before,
1482
+ .fa-file-audio-o:before {
1483
+ content: "\f1c7";
1484
+ }
1485
+ .fa-file-movie-o:before,
1486
+ .fa-file-video-o:before {
1487
+ content: "\f1c8";
1488
+ }
1489
+ .fa-file-code-o:before {
1490
+ content: "\f1c9";
1491
+ }
1492
+ .fa-vine:before {
1493
+ content: "\f1ca";
1494
+ }
1495
+ .fa-codepen:before {
1496
+ content: "\f1cb";
1497
+ }
1498
+ .fa-jsfiddle:before {
1499
+ content: "\f1cc";
1500
+ }
1501
+ .fa-life-bouy:before,
1502
+ .fa-life-buoy:before,
1503
+ .fa-life-saver:before,
1504
+ .fa-support:before,
1505
+ .fa-life-ring:before {
1506
+ content: "\f1cd";
1507
+ }
1508
+ .fa-circle-o-notch:before {
1509
+ content: "\f1ce";
1510
+ }
1511
+ .fa-ra:before,
1512
+ .fa-resistance:before,
1513
+ .fa-rebel:before {
1514
+ content: "\f1d0";
1515
+ }
1516
+ .fa-ge:before,
1517
+ .fa-empire:before {
1518
+ content: "\f1d1";
1519
+ }
1520
+ .fa-git-square:before {
1521
+ content: "\f1d2";
1522
+ }
1523
+ .fa-git:before {
1524
+ content: "\f1d3";
1525
+ }
1526
+ .fa-y-combinator-square:before,
1527
+ .fa-yc-square:before,
1528
+ .fa-hacker-news:before {
1529
+ content: "\f1d4";
1530
+ }
1531
+ .fa-tencent-weibo:before {
1532
+ content: "\f1d5";
1533
+ }
1534
+ .fa-qq:before {
1535
+ content: "\f1d6";
1536
+ }
1537
+ .fa-wechat:before,
1538
+ .fa-weixin:before {
1539
+ content: "\f1d7";
1540
+ }
1541
+ .fa-send:before,
1542
+ .fa-paper-plane:before {
1543
+ content: "\f1d8";
1544
+ }
1545
+ .fa-send-o:before,
1546
+ .fa-paper-plane-o:before {
1547
+ content: "\f1d9";
1548
+ }
1549
+ .fa-history:before {
1550
+ content: "\f1da";
1551
+ }
1552
+ .fa-circle-thin:before {
1553
+ content: "\f1db";
1554
+ }
1555
+ .fa-header:before {
1556
+ content: "\f1dc";
1557
+ }
1558
+ .fa-paragraph:before {
1559
+ content: "\f1dd";
1560
+ }
1561
+ .fa-sliders:before {
1562
+ content: "\f1de";
1563
+ }
1564
+ .fa-share-alt:before {
1565
+ content: "\f1e0";
1566
+ }
1567
+ .fa-share-alt-square:before {
1568
+ content: "\f1e1";
1569
+ }
1570
+ .fa-bomb:before {
1571
+ content: "\f1e2";
1572
+ }
1573
+ .fa-soccer-ball-o:before,
1574
+ .fa-futbol-o:before {
1575
+ content: "\f1e3";
1576
+ }
1577
+ .fa-tty:before {
1578
+ content: "\f1e4";
1579
+ }
1580
+ .fa-binoculars:before {
1581
+ content: "\f1e5";
1582
+ }
1583
+ .fa-plug:before {
1584
+ content: "\f1e6";
1585
+ }
1586
+ .fa-slideshare:before {
1587
+ content: "\f1e7";
1588
+ }
1589
+ .fa-twitch:before {
1590
+ content: "\f1e8";
1591
+ }
1592
+ .fa-yelp:before {
1593
+ content: "\f1e9";
1594
+ }
1595
+ .fa-newspaper-o:before {
1596
+ content: "\f1ea";
1597
+ }
1598
+ .fa-wifi:before {
1599
+ content: "\f1eb";
1600
+ }
1601
+ .fa-calculator:before {
1602
+ content: "\f1ec";
1603
+ }
1604
+ .fa-paypal:before {
1605
+ content: "\f1ed";
1606
+ }
1607
+ .fa-google-wallet:before {
1608
+ content: "\f1ee";
1609
+ }
1610
+ .fa-cc-visa:before {
1611
+ content: "\f1f0";
1612
+ }
1613
+ .fa-cc-mastercard:before {
1614
+ content: "\f1f1";
1615
+ }
1616
+ .fa-cc-discover:before {
1617
+ content: "\f1f2";
1618
+ }
1619
+ .fa-cc-amex:before {
1620
+ content: "\f1f3";
1621
+ }
1622
+ .fa-cc-paypal:before {
1623
+ content: "\f1f4";
1624
+ }
1625
+ .fa-cc-stripe:before {
1626
+ content: "\f1f5";
1627
+ }
1628
+ .fa-bell-slash:before {
1629
+ content: "\f1f6";
1630
+ }
1631
+ .fa-bell-slash-o:before {
1632
+ content: "\f1f7";
1633
+ }
1634
+ .fa-trash:before {
1635
+ content: "\f1f8";
1636
+ }
1637
+ .fa-copyright:before {
1638
+ content: "\f1f9";
1639
+ }
1640
+ .fa-at:before {
1641
+ content: "\f1fa";
1642
+ }
1643
+ .fa-eyedropper:before {
1644
+ content: "\f1fb";
1645
+ }
1646
+ .fa-paint-brush:before {
1647
+ content: "\f1fc";
1648
+ }
1649
+ .fa-birthday-cake:before {
1650
+ content: "\f1fd";
1651
+ }
1652
+ .fa-area-chart:before {
1653
+ content: "\f1fe";
1654
+ }
1655
+ .fa-pie-chart:before {
1656
+ content: "\f200";
1657
+ }
1658
+ .fa-line-chart:before {
1659
+ content: "\f201";
1660
+ }
1661
+ .fa-lastfm:before {
1662
+ content: "\f202";
1663
+ }
1664
+ .fa-lastfm-square:before {
1665
+ content: "\f203";
1666
+ }
1667
+ .fa-toggle-off:before {
1668
+ content: "\f204";
1669
+ }
1670
+ .fa-toggle-on:before {
1671
+ content: "\f205";
1672
+ }
1673
+ .fa-bicycle:before {
1674
+ content: "\f206";
1675
+ }
1676
+ .fa-bus:before {
1677
+ content: "\f207";
1678
+ }
1679
+ .fa-ioxhost:before {
1680
+ content: "\f208";
1681
+ }
1682
+ .fa-angellist:before {
1683
+ content: "\f209";
1684
+ }
1685
+ .fa-cc:before {
1686
+ content: "\f20a";
1687
+ }
1688
+ .fa-shekel:before,
1689
+ .fa-sheqel:before,
1690
+ .fa-ils:before {
1691
+ content: "\f20b";
1692
+ }
1693
+ .fa-meanpath:before {
1694
+ content: "\f20c";
1695
+ }
1696
+ .fa-buysellads:before {
1697
+ content: "\f20d";
1698
+ }
1699
+ .fa-connectdevelop:before {
1700
+ content: "\f20e";
1701
+ }
1702
+ .fa-dashcube:before {
1703
+ content: "\f210";
1704
+ }
1705
+ .fa-forumbee:before {
1706
+ content: "\f211";
1707
+ }
1708
+ .fa-leanpub:before {
1709
+ content: "\f212";
1710
+ }
1711
+ .fa-sellsy:before {
1712
+ content: "\f213";
1713
+ }
1714
+ .fa-shirtsinbulk:before {
1715
+ content: "\f214";
1716
+ }
1717
+ .fa-simplybuilt:before {
1718
+ content: "\f215";
1719
+ }
1720
+ .fa-skyatlas:before {
1721
+ content: "\f216";
1722
+ }
1723
+ .fa-cart-plus:before {
1724
+ content: "\f217";
1725
+ }
1726
+ .fa-cart-arrow-down:before {
1727
+ content: "\f218";
1728
+ }
1729
+ .fa-diamond:before {
1730
+ content: "\f219";
1731
+ }
1732
+ .fa-ship:before {
1733
+ content: "\f21a";
1734
+ }
1735
+ .fa-user-secret:before {
1736
+ content: "\f21b";
1737
+ }
1738
+ .fa-motorcycle:before {
1739
+ content: "\f21c";
1740
+ }
1741
+ .fa-street-view:before {
1742
+ content: "\f21d";
1743
+ }
1744
+ .fa-heartbeat:before {
1745
+ content: "\f21e";
1746
+ }
1747
+ .fa-venus:before {
1748
+ content: "\f221";
1749
+ }
1750
+ .fa-mars:before {
1751
+ content: "\f222";
1752
+ }
1753
+ .fa-mercury:before {
1754
+ content: "\f223";
1755
+ }
1756
+ .fa-intersex:before,
1757
+ .fa-transgender:before {
1758
+ content: "\f224";
1759
+ }
1760
+ .fa-transgender-alt:before {
1761
+ content: "\f225";
1762
+ }
1763
+ .fa-venus-double:before {
1764
+ content: "\f226";
1765
+ }
1766
+ .fa-mars-double:before {
1767
+ content: "\f227";
1768
+ }
1769
+ .fa-venus-mars:before {
1770
+ content: "\f228";
1771
+ }
1772
+ .fa-mars-stroke:before {
1773
+ content: "\f229";
1774
+ }
1775
+ .fa-mars-stroke-v:before {
1776
+ content: "\f22a";
1777
+ }
1778
+ .fa-mars-stroke-h:before {
1779
+ content: "\f22b";
1780
+ }
1781
+ .fa-neuter:before {
1782
+ content: "\f22c";
1783
+ }
1784
+ .fa-genderless:before {
1785
+ content: "\f22d";
1786
+ }
1787
+ .fa-facebook-official:before {
1788
+ content: "\f230";
1789
+ }
1790
+ .fa-pinterest-p:before {
1791
+ content: "\f231";
1792
+ }
1793
+ .fa-whatsapp:before {
1794
+ content: "\f232";
1795
+ }
1796
+ .fa-server:before {
1797
+ content: "\f233";
1798
+ }
1799
+ .fa-user-plus:before {
1800
+ content: "\f234";
1801
+ }
1802
+ .fa-user-times:before {
1803
+ content: "\f235";
1804
+ }
1805
+ .fa-hotel:before,
1806
+ .fa-bed:before {
1807
+ content: "\f236";
1808
+ }
1809
+ .fa-viacoin:before {
1810
+ content: "\f237";
1811
+ }
1812
+ .fa-train:before {
1813
+ content: "\f238";
1814
+ }
1815
+ .fa-subway:before {
1816
+ content: "\f239";
1817
+ }
1818
+ .fa-medium:before {
1819
+ content: "\f23a";
1820
+ }
1821
+ .fa-yc:before,
1822
+ .fa-y-combinator:before {
1823
+ content: "\f23b";
1824
+ }
1825
+ .fa-optin-monster:before {
1826
+ content: "\f23c";
1827
+ }
1828
+ .fa-opencart:before {
1829
+ content: "\f23d";
1830
+ }
1831
+ .fa-expeditedssl:before {
1832
+ content: "\f23e";
1833
+ }
1834
+ .fa-battery-4:before,
1835
+ .fa-battery-full:before {
1836
+ content: "\f240";
1837
+ }
1838
+ .fa-battery-3:before,
1839
+ .fa-battery-three-quarters:before {
1840
+ content: "\f241";
1841
+ }
1842
+ .fa-battery-2:before,
1843
+ .fa-battery-half:before {
1844
+ content: "\f242";
1845
+ }
1846
+ .fa-battery-1:before,
1847
+ .fa-battery-quarter:before {
1848
+ content: "\f243";
1849
+ }
1850
+ .fa-battery-0:before,
1851
+ .fa-battery-empty:before {
1852
+ content: "\f244";
1853
+ }
1854
+ .fa-mouse-pointer:before {
1855
+ content: "\f245";
1856
+ }
1857
+ .fa-i-cursor:before {
1858
+ content: "\f246";
1859
+ }
1860
+ .fa-object-group:before {
1861
+ content: "\f247";
1862
+ }
1863
+ .fa-object-ungroup:before {
1864
+ content: "\f248";
1865
+ }
1866
+ .fa-sticky-note:before {
1867
+ content: "\f249";
1868
+ }
1869
+ .fa-sticky-note-o:before {
1870
+ content: "\f24a";
1871
+ }
1872
+ .fa-cc-jcb:before {
1873
+ content: "\f24b";
1874
+ }
1875
+ .fa-cc-diners-club:before {
1876
+ content: "\f24c";
1877
+ }
1878
+ .fa-clone:before {
1879
+ content: "\f24d";
1880
+ }
1881
+ .fa-balance-scale:before {
1882
+ content: "\f24e";
1883
+ }
1884
+ .fa-hourglass-o:before {
1885
+ content: "\f250";
1886
+ }
1887
+ .fa-hourglass-1:before,
1888
+ .fa-hourglass-start:before {
1889
+ content: "\f251";
1890
+ }
1891
+ .fa-hourglass-2:before,
1892
+ .fa-hourglass-half:before {
1893
+ content: "\f252";
1894
+ }
1895
+ .fa-hourglass-3:before,
1896
+ .fa-hourglass-end:before {
1897
+ content: "\f253";
1898
+ }
1899
+ .fa-hourglass:before {
1900
+ content: "\f254";
1901
+ }
1902
+ .fa-hand-grab-o:before,
1903
+ .fa-hand-rock-o:before {
1904
+ content: "\f255";
1905
+ }
1906
+ .fa-hand-stop-o:before,
1907
+ .fa-hand-paper-o:before {
1908
+ content: "\f256";
1909
+ }
1910
+ .fa-hand-scissors-o:before {
1911
+ content: "\f257";
1912
+ }
1913
+ .fa-hand-lizard-o:before {
1914
+ content: "\f258";
1915
+ }
1916
+ .fa-hand-spock-o:before {
1917
+ content: "\f259";
1918
+ }
1919
+ .fa-hand-pointer-o:before {
1920
+ content: "\f25a";
1921
+ }
1922
+ .fa-hand-peace-o:before {
1923
+ content: "\f25b";
1924
+ }
1925
+ .fa-trademark:before {
1926
+ content: "\f25c";
1927
+ }
1928
+ .fa-registered:before {
1929
+ content: "\f25d";
1930
+ }
1931
+ .fa-creative-commons:before {
1932
+ content: "\f25e";
1933
+ }
1934
+ .fa-gg:before {
1935
+ content: "\f260";
1936
+ }
1937
+ .fa-gg-circle:before {
1938
+ content: "\f261";
1939
+ }
1940
+ .fa-tripadvisor:before {
1941
+ content: "\f262";
1942
+ }
1943
+ .fa-odnoklassniki:before {
1944
+ content: "\f263";
1945
+ }
1946
+ .fa-odnoklassniki-square:before {
1947
+ content: "\f264";
1948
+ }
1949
+ .fa-get-pocket:before {
1950
+ content: "\f265";
1951
+ }
1952
+ .fa-wikipedia-w:before {
1953
+ content: "\f266";
1954
+ }
1955
+ .fa-safari:before {
1956
+ content: "\f267";
1957
+ }
1958
+ .fa-chrome:before {
1959
+ content: "\f268";
1960
+ }
1961
+ .fa-firefox:before {
1962
+ content: "\f269";
1963
+ }
1964
+ .fa-opera:before {
1965
+ content: "\f26a";
1966
+ }
1967
+ .fa-internet-explorer:before {
1968
+ content: "\f26b";
1969
+ }
1970
+ .fa-tv:before,
1971
+ .fa-television:before {
1972
+ content: "\f26c";
1973
+ }
1974
+ .fa-contao:before {
1975
+ content: "\f26d";
1976
+ }
1977
+ .fa-500px:before {
1978
+ content: "\f26e";
1979
+ }
1980
+ .fa-amazon:before {
1981
+ content: "\f270";
1982
+ }
1983
+ .fa-calendar-plus-o:before {
1984
+ content: "\f271";
1985
+ }
1986
+ .fa-calendar-minus-o:before {
1987
+ content: "\f272";
1988
+ }
1989
+ .fa-calendar-times-o:before {
1990
+ content: "\f273";
1991
+ }
1992
+ .fa-calendar-check-o:before {
1993
+ content: "\f274";
1994
+ }
1995
+ .fa-industry:before {
1996
+ content: "\f275";
1997
+ }
1998
+ .fa-map-pin:before {
1999
+ content: "\f276";
2000
+ }
2001
+ .fa-map-signs:before {
2002
+ content: "\f277";
2003
+ }
2004
+ .fa-map-o:before {
2005
+ content: "\f278";
2006
+ }
2007
+ .fa-map:before {
2008
+ content: "\f279";
2009
+ }
2010
+ .fa-commenting:before {
2011
+ content: "\f27a";
2012
+ }
2013
+ .fa-commenting-o:before {
2014
+ content: "\f27b";
2015
+ }
2016
+ .fa-houzz:before {
2017
+ content: "\f27c";
2018
+ }
2019
+ .fa-vimeo:before {
2020
+ content: "\f27d";
2021
+ }
2022
+ .fa-black-tie:before {
2023
+ content: "\f27e";
2024
+ }
2025
+ .fa-fonticons:before {
2026
+ content: "\f280";
2027
+ }
2028
+ .fa-reddit-alien:before {
2029
+ content: "\f281";
2030
+ }
2031
+ .fa-edge:before {
2032
+ content: "\f282";
2033
+ }
2034
+ .fa-credit-card-alt:before {
2035
+ content: "\f283";
2036
+ }
2037
+ .fa-codiepie:before {
2038
+ content: "\f284";
2039
+ }
2040
+ .fa-modx:before {
2041
+ content: "\f285";
2042
+ }
2043
+ .fa-fort-awesome:before {
2044
+ content: "\f286";
2045
+ }
2046
+ .fa-usb:before {
2047
+ content: "\f287";
2048
+ }
2049
+ .fa-product-hunt:before {
2050
+ content: "\f288";
2051
+ }
2052
+ .fa-mixcloud:before {
2053
+ content: "\f289";
2054
+ }
2055
+ .fa-scribd:before {
2056
+ content: "\f28a";
2057
+ }
2058
+ .fa-pause-circle:before {
2059
+ content: "\f28b";
2060
+ }
2061
+ .fa-pause-circle-o:before {
2062
+ content: "\f28c";
2063
+ }
2064
+ .fa-stop-circle:before {
2065
+ content: "\f28d";
2066
+ }
2067
+ .fa-stop-circle-o:before {
2068
+ content: "\f28e";
2069
+ }
2070
+ .fa-shopping-bag:before {
2071
+ content: "\f290";
2072
+ }
2073
+ .fa-shopping-basket:before {
2074
+ content: "\f291";
2075
+ }
2076
+ .fa-hashtag:before {
2077
+ content: "\f292";
2078
+ }
2079
+ .fa-bluetooth:before {
2080
+ content: "\f293";
2081
+ }
2082
+ .fa-bluetooth-b:before {
2083
+ content: "\f294";
2084
+ }
2085
+ .fa-percent:before {
2086
+ content: "\f295";
2087
+ }
2088
+ .fa-gitlab:before {
2089
+ content: "\f296";
2090
+ }
2091
+ .fa-wpbeginner:before {
2092
+ content: "\f297";
2093
+ }
2094
+ .fa-wpforms:before {
2095
+ content: "\f298";
2096
+ }
2097
+ .fa-envira:before {
2098
+ content: "\f299";
2099
+ }
2100
+ .fa-universal-access:before {
2101
+ content: "\f29a";
2102
+ }
2103
+ .fa-wheelchair-alt:before {
2104
+ content: "\f29b";
2105
+ }
2106
+ .fa-question-circle-o:before {
2107
+ content: "\f29c";
2108
+ }
2109
+ .fa-blind:before {
2110
+ content: "\f29d";
2111
+ }
2112
+ .fa-audio-description:before {
2113
+ content: "\f29e";
2114
+ }
2115
+ .fa-volume-control-phone:before {
2116
+ content: "\f2a0";
2117
+ }
2118
+ .fa-braille:before {
2119
+ content: "\f2a1";
2120
+ }
2121
+ .fa-assistive-listening-systems:before {
2122
+ content: "\f2a2";
2123
+ }
2124
+ .fa-asl-interpreting:before,
2125
+ .fa-american-sign-language-interpreting:before {
2126
+ content: "\f2a3";
2127
+ }
2128
+ .fa-deafness:before,
2129
+ .fa-hard-of-hearing:before,
2130
+ .fa-deaf:before {
2131
+ content: "\f2a4";
2132
+ }
2133
+ .fa-glide:before {
2134
+ content: "\f2a5";
2135
+ }
2136
+ .fa-glide-g:before {
2137
+ content: "\f2a6";
2138
+ }
2139
+ .fa-signing:before,
2140
+ .fa-sign-language:before {
2141
+ content: "\f2a7";
2142
+ }
2143
+ .fa-low-vision:before {
2144
+ content: "\f2a8";
2145
+ }
2146
+ .fa-viadeo:before {
2147
+ content: "\f2a9";
2148
+ }
2149
+ .fa-viadeo-square:before {
2150
+ content: "\f2aa";
2151
+ }
2152
+ .fa-snapchat:before {
2153
+ content: "\f2ab";
2154
+ }
2155
+ .fa-snapchat-ghost:before {
2156
+ content: "\f2ac";
2157
+ }
2158
+ .fa-snapchat-square:before {
2159
+ content: "\f2ad";
2160
+ }
2161
+ .fa-pied-piper:before {
2162
+ content: "\f2ae";
2163
+ }
2164
+ .fa-first-order:before {
2165
+ content: "\f2b0";
2166
+ }
2167
+ .fa-yoast:before {
2168
+ content: "\f2b1";
2169
+ }
2170
+ .fa-themeisle:before {
2171
+ content: "\f2b2";
2172
+ }
2173
+ .fa-google-plus-circle:before,
2174
+ .fa-google-plus-official:before {
2175
+ content: "\f2b3";
2176
+ }
2177
+ .fa-fa:before,
2178
+ .fa-font-awesome:before {
2179
+ content: "\f2b4";
2180
+ }
2181
+ .sr-only {
2182
+ position: absolute;
2183
+ width: 1px;
2184
+ height: 1px;
2185
+ padding: 0;
2186
+ margin: -1px;
2187
+ overflow: hidden;
2188
+ clip: rect(0, 0, 0, 0);
2189
+ border: 0;
2190
+ }
2191
+ .sr-only-focusable:active,
2192
+ .sr-only-focusable:focus {
2193
+ position: static;
2194
+ width: auto;
2195
+ height: auto;
2196
+ margin: 0;
2197
+ overflow: visible;
2198
+ clip: auto;
2199
+ }
assets/css/font-awesome/font-awesome.min.css ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*!
2
+ * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome
3
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.6.3');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}
assets/css/images/index.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ //Nothing to see here
3
+
4
+ header( 'HTTP/1.0 403 Forbidden' );
assets/css/images/logo.png ADDED
Binary file
assets/css/images/logo@2x.png ADDED
Binary file
assets/css/images/mascot.png ADDED
Binary file
assets/css/images/mascot@2x.png ADDED
Binary file
assets/css/images/menu-icon.png ADDED
Binary file
assets/css/images/menu-icon@2x.png ADDED
Binary file
assets/css/images/monsterinsights.png ADDED
Binary file
assets/css/images/waves.png ADDED
Binary file
assets/css/images/waves@x2.png ADDED
Binary file
assets/css/index.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
- //Nothing to see here
3
-
4
  header( 'HTTP/1.0 403 Forbidden' );
1
+ <?php
2
+ //Nothing to see here
3
+
4
  header( 'HTTP/1.0 403 Forbidden' );
assets/css/jvectormap/jquery-jvectormap-2.0.3.css ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ svg {
2
+ touch-action: none;
3
+ }
4
+
5
+ .jvectormap-container {
6
+ width: 100%;
7
+ height: 100%;
8
+ position: relative;
9
+ overflow: hidden;
10
+ touch-action: none;
11
+ }
12
+
13
+ .jvectormap-tip {
14
+ position: absolute;
15
+ display: none;
16
+ border: solid 1px #CDCDCD;
17
+ border-radius: 3px;
18
+ background: #292929;
19
+ color: white;
20
+ font-family: sans-serif, Verdana;
21
+ font-size: smaller;
22
+ padding: 3px;
23
+ }
24
+
25
+ .jvectormap-zoomin, .jvectormap-zoomout, .jvectormap-goback {
26
+ position: absolute;
27
+ left: 10px;
28
+ border-radius: 3px;
29
+ background: #292929;
30
+ padding: 3px;
31
+ color: white;
32
+ cursor: pointer;
33
+ line-height: 10px;
34
+ text-align: center;
35
+ box-sizing: content-box;
36
+ }
37
+
38
+ .jvectormap-zoomin, .jvectormap-zoomout {
39
+ width: 10px;
40
+ height: 10px;
41
+ }
42
+
43
+ .jvectormap-zoomin {
44
+ top: 10px;
45
+ }
46
+
47
+ .jvectormap-zoomout {
48
+ top: 30px;
49
+ }
50
+
51
+ .jvectormap-goback {
52
+ bottom: 10px;
53
+ z-index: 1000;
54
+ padding: 6px;
55
+ }
56
+
57
+ .jvectormap-spinner {
58
+ position: absolute;
59
+ left: 0;
60
+ top: 0;
61
+ right: 0;
62
+ bottom: 0;
63
+ background: center no-repeat url(data:image/gif;base64,R0lGODlhIAAgAPMAAP///wAAAMbGxoSEhLa2tpqamjY2NlZWVtjY2OTk5Ly8vB4eHgQEBAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ/V/nmOM82XiHRLYKhKP1oZmADdEAAAh+QQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY/CZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB+A4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6+Ho7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq+B6QDtuetcaBPnW6+O7wDHpIiK9SaVK5GgV543tzjgGcghAgAh+QQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK++G+w48edZPK+M6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE+G+cD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm+FNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk+aV+oJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0/VNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc+XiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30/iI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE/jiuL04RGEBgwWhShRgQExHBAAh+QQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR+ipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY+Yip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd+MFCN6HAAIKgNggY0KtEBAAh+QQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1+vsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d+jYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg+ygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0+bm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h+Kr0SJ8MFihpNbx+4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX+BP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA==);
64
+ }
65
+
66
+ .jvectormap-legend-title {
67
+ font-weight: bold;
68
+ font-size: 14px;
69
+ text-align: center;
70
+ }
71
+
72
+ .jvectormap-legend-cnt {
73
+ position: absolute;
74
+ }
75
+
76
+ .jvectormap-legend-cnt-h {
77
+ bottom: 0;
78
+ right: 0;
79
+ }
80
+
81
+ .jvectormap-legend-cnt-v {
82
+ top: 0;
83
+ right: 0;
84
+ }
85
+
86
+ .jvectormap-legend {
87
+ background: black;
88
+ color: white;
89
+ border-radius: 3px;
90
+ }
91
+
92
+ .jvectormap-legend-cnt-h .jvectormap-legend {
93
+ float: left;
94
+ margin: 0 10px 10px 0;
95
+ padding: 3px 3px 1px 3px;
96
+ }
97
+
98
+ .jvectormap-legend-cnt-h .jvectormap-legend .jvectormap-legend-tick {
99
+ float: left;
100
+ }
101
+
102
+ .jvectormap-legend-cnt-v .jvectormap-legend {
103
+ margin: 10px 10px 0 0;
104
+ padding: 3px;
105
+ }
106
+
107
+ .jvectormap-legend-cnt-h .jvectormap-legend-tick {
108
+ width: 40px;
109
+ }
110
+
111
+ .jvectormap-legend-cnt-h .jvectormap-legend-tick-sample {
112
+ height: 15px;
113
+ }
114
+
115
+ .jvectormap-legend-cnt-v .jvectormap-legend-tick-sample {
116
+ height: 20px;
117
+ width: 20px;
118
+ display: inline-block;
119
+ vertical-align: middle;
120
+ }
121
+
122
+ .jvectormap-legend-tick-text {
123
+ font-size: 12px;
124
+ }
125
+
126
+ .jvectormap-legend-cnt-h .jvectormap-legend-tick-text {
127
+ text-align: center;
128
+ }
129
+
130
+ .jvectormap-legend-cnt-v .jvectormap-legend-tick-text {
131
+ display: inline-block;
132
+ vertical-align: middle;
133
+ line-height: 20px;
134
+ padding-left: 3px;
135
+ }
assets/css/select2/index.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ //Nothing to see here
3
+
4
+ header( 'HTTP/1.0 403 Forbidden' );
assets/css/select2/select2.css ADDED
@@ -0,0 +1,484 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .select2-container {
2
+ box-sizing: border-box;
3
+ display: inline-block;
4
+ margin: 0;
5
+ position: relative;
6
+ vertical-align: middle; }
7
+ .select2-container .select2-selection--single {
8
+ box-sizing: border-box;
9
+ cursor: pointer;
10
+ display: block;
11
+ height: 28px;
12
+ user-select: none;
13
+ -webkit-user-select: none; }
14
+ .select2-container .select2-selection--single .select2-selection__rendered {
15
+ display: block;
16
+ padding-left: 8px;
17
+ padding-right: 20px;
18
+ overflow: hidden;
19
+ text-overflow: ellipsis;
20
+ white-space: nowrap; }
21
+ .select2-container .select2-selection--single .select2-selection__clear {
22
+ position: relative; }
23
+ .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
24
+ padding-right: 8px;
25
+ padding-left: 20px; }
26
+ .select2-container .select2-selection--multiple {
27
+ box-sizing: border-box;
28
+ cursor: pointer;
29
+ display: block;
30
+ min-height: 32px;
31
+ user-select: none;
32
+ -webkit-user-select: none; }
33
+ .select2-container .select2-selection--multiple .select2-selection__rendered {
34
+ display: inline-block;
35
+ overflow: hidden;
36
+ padding-left: 8px;
37
+ text-overflow: ellipsis;
38
+ white-space: nowrap; }
39
+ .select2-container .select2-search--inline {
40
+ float: left; }
41
+ .select2-container .select2-search--inline .select2-search__field {
42
+ box-sizing: border-box;
43
+ border: none;
44
+ font-size: 100%;
45
+ margin-top: 5px;
46
+ padding: 0; }
47
+ .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
48
+ -webkit-appearance: none; }
49
+
50
+ .select2-dropdown {
51
+ background-color: white;
52
+ border: 1px solid #aaa;
53
+ border-radius: 4px;
54
+ box-sizing: border-box;
55
+ display: block;
56
+ position: absolute;
57
+ left: -100000px;
58
+ width: 100%;
59
+ z-index: 1051; }
60
+
61
+ .select2-results {
62
+ display: block; }
63
+
64
+ .select2-results__options {
65
+ list-style: none;
66
+ margin: 0;
67
+ padding: 0; }
68
+
69
+ .select2-results__option {
70
+ padding: 6px;
71
+ user-select: none;
72
+ -webkit-user-select: none; }
73
+ .select2-results__option[aria-selected] {
74
+ cursor: pointer; }
75
+
76
+ .select2-container--open .select2-dropdown {
77
+ left: 0; }
78
+
79
+ .select2-container--open .select2-dropdown--above {
80
+ border-bottom: none;
81
+ border-bottom-left-radius: 0;
82
+ border-bottom-right-radius: 0; }
83
+
84
+ .select2-container--open .select2-dropdown--below {
85
+ border-top: none;
86
+ border-top-left-radius: 0;
87
+ border-top-right-radius: 0; }
88
+
89
+ .select2-search--dropdown {
90
+ display: block;
91
+ padding: 4px; }
92
+ .select2-search--dropdown .select2-search__field {
93
+ padding: 4px;
94
+ width: 100%;
95
+ box-sizing: border-box; }
96
+ .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
97
+ -webkit-appearance: none; }
98
+ .select2-search--dropdown.select2-search--hide {
99
+ display: none; }
100
+
101
+ .select2-close-mask {
102
+ border: 0;
103
+ margin: 0;
104
+ padding: 0;
105
+ display: block;
106
+ position: fixed;
107
+ left: 0;
108
+ top: 0;
109
+ min-height: 100%;
110
+ min-width: 100%;
111
+ height: auto;
112
+ width: auto;
113
+ opacity: 0;
114
+ z-index: 99;
115
+ background-color: #fff;
116
+ filter: alpha(opacity=0); }
117
+
118
+ .select2-hidden-accessible {
119
+ border: 0 !important;
120
+ clip: rect(0 0 0 0) !important;
121
+ height: 1px !important;
122
+ margin: -1px !important;
123
+ overflow: hidden !important;
124
+ padding: 0 !important;
125
+ position: absolute !important;
126
+ width: 1px !important; }
127
+
128
+ .select2-container--default .select2-selection--single {
129
+ background-color: #fff;
130
+ border: 1px solid #aaa;
131
+ border-radius: 4px; }
132
+ .select2-container--default .select2-selection--single .select2-selection__rendered {
133
+ color: #444;
134
+ line-height: 28px; }
135
+ .select2-container--default .select2-selection--single .select2-selection__clear {
136
+ cursor: pointer;
137
+ float: right;
138
+ font-weight: bold; }
139
+ .select2-container--default .select2-selection--single .select2-selection__placeholder {
140
+ color: #999; }
141
+ .select2-container--default .select2-selection--single .select2-selection__arrow {
142
+ height: 26px;
143
+ position: absolute;
144
+ top: 1px;
145
+ right: 1px;
146
+ width: 20px; }
147
+ .select2-container--default .select2-selection--single .select2-selection__arrow b {
148
+ border-color: #888 transparent transparent transparent;
149
+ border-style: solid;
150
+ border-width: 5px 4px 0 4px;
151
+ height: 0;
152
+ left: 50%;
153
+ margin-left: -4px;
154
+ margin-top: -2px;
155
+ position: absolute;
156
+ top: 50%;
157
+ width: 0; }
158
+
159
+ .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
160
+ float: left; }
161
+
162
+ .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
163
+ left: 1px;
164
+ right: auto; }
165
+
166
+ .select2-container--default.select2-container--disabled .select2-selection--single {
167
+ background-color: #eee;
168
+ cursor: default; }
169
+ .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
170
+ display: none; }
171
+
172
+ .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
173
+ border-color: transparent transparent #888 transparent;
174
+ border-width: 0 4px 5px 4px; }
175
+
176
+ .select2-container--default .select2-selection--multiple {
177
+ background-color: white;
178
+ border: 1px solid #aaa;
179
+ border-radius: 4px;
180
+ cursor: text; }
181
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered {
182
+ box-sizing: border-box;
183
+ list-style: none;
184
+ margin: 0;
185
+ padding: 0 5px;
186
+ width: 100%; }
187
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
188
+ list-style: none; }
189
+ .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
190
+ color: #999;
191
+ margin-top: 5px;
192
+ float: left; }
193
+ .select2-container--default .select2-selection--multiple .select2-selection__clear {
194
+ cursor: pointer;
195
+ float: right;
196
+ font-weight: bold;
197
+ margin-top: 5px;
198
+ margin-right: 10px; }
199
+ .select2-container--default .select2-selection--multiple .select2-selection__choice {
200
+ background-color: #e4e4e4;
201
+ border: 1px solid #aaa;
202
+ border-radius: 4px;
203
+ cursor: default;
204
+ float: left;
205
+ margin-right: 5px;
206
+ margin-top: 5px;
207
+ padding: 0 5px; }
208
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
209
+ color: #999;
210
+ cursor: pointer;
211
+ display: inline-block;
212
+ font-weight: bold;
213
+ margin-right: 2px; }
214
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
215
+ color: #333; }
216
+
217
+ .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
218
+ float: right; }
219
+
220
+ .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
221
+ margin-left: 5px;
222
+ margin-right: auto; }
223
+
224
+ .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
225
+ margin-left: 2px;
226
+ margin-right: auto; }
227
+
228
+ .select2-container--default.select2-container--focus .select2-selection--multiple {
229
+ border: solid black 1px;
230
+ outline: 0; }
231
+
232
+ .select2-container--default.select2-container--disabled .select2-selection--multiple {
233
+ background-color: #eee;
234
+ cursor: default; }
235
+
236
+ .select2-container--default.select2-container--disabled .select2-selection__choice__remove {
237
+ display: none; }
238
+
239
+ .select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
240
+ border-top-left-radius: 0;
241
+ border-top-right-radius: 0; }
242
+
243
+ .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
244
+ border-bottom-left-radius: 0;
245
+ border-bottom-right-radius: 0; }
246
+
247
+ .select2-container--default .select2-search--dropdown .select2-search__field {
248
+ border: 1px solid #aaa; }
249
+
250
+ .select2-container--default .select2-search--inline .select2-search__field {
251
+ background: transparent;
252
+ border: none;
253
+ outline: 0;
254
+ box-shadow: none;
255
+ -webkit-appearance: textfield; }
256
+
257
+ .select2-container--default .select2-results > .select2-results__options {
258
+ max-height: 200px;
259
+ overflow-y: auto; }
260
+
261
+ .select2-container--default .select2-results__option[role=group] {
262
+ padding: 0; }
263
+
264
+ .select2-container--default .select2-results__option[aria-disabled=true] {
265
+ color: #999; }
266
+
267
+ .select2-container--default .select2-results__option[aria-selected=true] {
268
+ background-color: #ddd; }
269
+
270
+ .select2-container--default .select2-results__option .select2-results__option {
271
+ padding-left: 1em; }
272
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__group {
273
+ padding-left: 0; }
274
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option {
275
+ margin-left: -1em;
276
+ padding-left: 2em; }
277
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
278
+ margin-left: -2em;
279
+ padding-left: 3em; }
280
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
281
+ margin-left: -3em;
282
+ padding-left: 4em; }
283
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
284
+ margin-left: -4em;
285
+ padding-left: 5em; }
286
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
287
+ margin-left: -5em;
288
+ padding-left: 6em; }
289
+
290
+ .select2-container--default .select2-results__option--highlighted[aria-selected] {
291
+ background-color: #5897fb;
292
+ color: white; }
293
+
294
+ .select2-container--default .select2-results__group {
295
+ cursor: default;
296
+ display: block;
297
+ padding: 6px; }
298
+
299
+ .select2-container--classic .select2-selection--single {
300
+ background-color: #f7f7f7;
301
+ border: 1px solid #aaa;
302
+ border-radius: 4px;
303
+ outline: 0;
304
+ background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
305
+ background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
306
+ background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
307
+ background-repeat: repeat-x;
308
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
309
+ .select2-container--classic .select2-selection--single:focus {
310
+ border: 1px solid #5897fb; }
311
+ .select2-container--classic .select2-selection--single .select2-selection__rendered {
312
+ color: #444;
313
+ line-height: 28px; }
314
+ .select2-container--classic .select2-selection--single .select2-selection__clear {
315
+ cursor: pointer;
316
+ float: right;
317
+ font-weight: bold;
318
+ margin-right: 10px; }
319
+ .select2-container--classic .select2-selection--single .select2-selection__placeholder {
320
+ color: #999; }
321
+ .select2-container--classic .select2-selection--single .select2-selection__arrow {
322
+ background-color: #ddd;
323
+ border: none;
324
+ border-left: 1px solid #aaa;
325
+ border-top-right-radius: 4px;
326
+ border-bottom-right-radius: 4px;
327
+ height: 26px;
328
+ position: absolute;
329
+ top: 1px;
330
+ right: 1px;
331
+ width: 20px;
332
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
333
+ background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
334
+ background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
335
+ background-repeat: repeat-x;
336
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
337
+ .select2-container--classic .select2-selection--single .select2-selection__arrow b {
338
+ border-color: #888 transparent transparent transparent;
339
+ border-style: solid;
340
+ border-width: 5px 4px 0 4px;
341
+ height: 0;
342
+ left: 50%;
343
+ margin-left: -4px;
344
+ margin-top: -2px;
345
+ position: absolute;
346
+ top: 50%;
347
+ width: 0; }
348
+
349
+ .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
350
+ float: left; }
351
+
352
+ .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
353
+ border: none;
354
+ border-right: 1px solid #aaa;
355
+ border-radius: 0;
356
+ border-top-left-radius: 4px;
357
+ border-bottom-left-radius: 4px;
358
+ left: 1px;
359
+ right: auto; }
360
+
361
+ .select2-container--classic.select2-container--open .select2-selection--single {
362
+ border: 1px solid #5897fb; }
363
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
364
+ background: transparent;
365
+ border: none; }
366
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
367
+ border-color: transparent transparent #888 transparent;
368
+ border-width: 0 4px 5px 4px; }
369
+
370
+ .select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
371
+ border-top: none;
372
+ border-top-left-radius: 0;
373
+ border-top-right-radius: 0;
374
+ background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
375
+ background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
376
+ background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
377
+ background-repeat: repeat-x;
378
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
379
+
380
+ .select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
381
+ border-bottom: none;
382
+ border-bottom-left-radius: 0;
383
+ border-bottom-right-radius: 0;
384
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
385
+ background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
386
+ background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
387
+ background-repeat: repeat-x;
388
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
389
+
390
+ .select2-container--classic .select2-selection--multiple {
391
+ background-color: white;
392
+ border: 1px solid #aaa;
393
+ border-radius: 4px;
394
+ cursor: text;
395
+ outline: 0; }
396
+ .select2-container--classic .select2-selection--multiple:focus {
397
+ border: 1px solid #5897fb; }
398
+ .select2-container--classic .select2-selection--multiple .select2-selection__rendered {
399
+ list-style: none;
400
+ margin: 0;
401
+ padding: 0 5px; }
402
+ .select2-container--classic .select2-selection--multiple .select2-selection__clear {
403
+ display: none; }
404
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice {
405
+ background-color: #e4e4e4;
406
+ border: 1px solid #aaa;
407
+ border-radius: 4px;
408
+ cursor: default;
409
+ float: left;
410
+ margin-right: 5px;
411
+ margin-top: 5px;
412
+ padding: 0 5px; }
413
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
414
+ color: #888;
415
+ cursor: pointer;
416
+ display: inline-block;
417
+ font-weight: bold;
418
+ margin-right: 2px; }
419
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
420
+ color: #555; }
421
+
422
+ .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
423
+ float: right; }
424
+
425
+ .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
426
+ margin-left: 5px;
427
+ margin-right: auto; }
428
+
429
+ .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
430
+ margin-left: 2px;
431
+ margin-right: auto; }
432
+
433
+ .select2-container--classic.select2-container--open .select2-selection--multiple {
434
+ border: 1px solid #5897fb; }
435
+
436
+ .select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
437
+ border-top: none;
438
+ border-top-left-radius: 0;
439
+ border-top-right-radius: 0; }
440
+
441
+ .select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
442
+ border-bottom: none;
443
+ border-bottom-left-radius: 0;
444
+ border-bottom-right-radius: 0; }
445
+
446
+ .select2-container--classic .select2-search--dropdown .select2-search__field {
447
+ border: 1px solid #aaa;
448
+ outline: 0; }
449
+
450
+ .select2-container--classic .select2-search--inline .select2-search__field {
451
+ outline: 0;
452
+ box-shadow: none; }
453
+
454
+ .select2-container--classic .select2-dropdown {
455
+ background-color: white;
456
+ border: 1px solid transparent; }
457
+
458
+ .select2-container--classic .select2-dropdown--above {
459
+ border-bottom: none; }
460
+
461
+ .select2-container--classic .select2-dropdown--below {
462
+ border-top: none; }
463
+
464
+ .select2-container--classic .select2-results > .select2-results__options {
465
+ max-height: 200px;
466
+ overflow-y: auto; }
467
+
468
+ .select2-container--classic .select2-results__option[role=group] {
469
+ padding: 0; }
470
+
471
+ .select2-container--classic .select2-results__option[aria-disabled=true] {
472
+ color: grey; }
473
+
474
+ .select2-container--classic .select2-results__option--highlighted[aria-selected] {
475
+ background-color: #3875d7;
476
+ color: white; }
477
+
478
+ .select2-container--classic .select2-results__group {
479
+ cursor: default;
480
+ display: block;
481
+ padding: 6px; }
482
+
483
+ .select2-container--classic.select2-container--open .select2-dropdown {
484
+ border-color: #5897fb; }
assets/css/select2/select2.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
assets/css/yoast_ga_admin_dashboard.css DELETED
@@ -1,76 +0,0 @@
1
- .yoast-graphs {
2
- display: inline-block;
3
- clear: both;
4
- position: relative;
5
- }
6
-
7
- .yoast-graph {
8
- display: inline;
9
- float: left;
10
- width: 840px;
11
- height: 315px;
12
- margin: 5px;
13
- }
14
-
15
- .yoast-graph-holder,
16
- .yoast-graph-yaxis {
17
- height: 240px;
18
- }
19
-
20
- .yoast-graph-holder,
21
- .yoast-graph-xaxis {
22
- width: 780px;
23
- }
24
-
25
- .yoast-graph-holder,
26
- .yoast-graph-yaxis,
27
- .yoast-graph-xaxis {
28
- float: left;
29
- }
30
-
31
- .yoast-graph-holder {
32
- margin: 0 5px 0 0;
33
- background: #fff;
34
- }
35
-
36
- .yoast-graph-xaxis {
37
- height: 20px;
38
- margin-left: 50px;
39
- }
40
-
41
- .yoast-graph-yaxis {
42
- overflow: hidden;
43
- width: 50px;
44
- }
45
-
46
- .x_label {
47
- display: none;
48
- }
49
-
50
- .yoast-data-table {
51
- margin: 25px 0 10px;
52
- }
53
-
54
- .yoast-dashboard h3 {
55
- float: left;
56
- clear: both;
57
- width: 100%;
58
- margin: 0 0 10px;
59
- }
60
-
61
- .yoast-dashboard .period {
62
- color: #555;
63
- font-size: 0.8em;
64
- font-weight: normal;
65
- font-style: italic;
66
- }
67
-
68
- .yoast-data-table table.dataTable thead .sorting,
69
- .yoast-data-table table.dataTable thead .sorting_asc,
70
- .yoast-data-table table.dataTable thead .sorting_desc {
71
- border-color: #d3d3d3;
72
- }
73
-
74
- .yoast-data-table table.dataTable.no-footer {
75
- border-bottom: none;
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/yoast_ga_admin_dashboard.min.css DELETED
@@ -1 +0,0 @@
1
- .yoast-graphs{display:inline-block;clear:both;position:relative}.yoast-graph{display:inline;float:left;width:840px;height:315px;margin:5px}.yoast-graph-holder,.yoast-graph-yaxis{height:240px}.yoast-graph-holder,.yoast-graph-xaxis{width:780px}.yoast-graph-holder,.yoast-graph-xaxis,.yoast-graph-yaxis{float:left}.yoast-graph-holder{margin:0 5px 0 0;background:#fff}.yoast-graph-xaxis{height:20px;margin-left:50px}.yoast-graph-yaxis{overflow:hidden;width:50px}.x_label{display:none}.yoast-data-table{margin:25px 0 10px}.yoast-dashboard h3{float:left;clear:both;width:100%;margin:0 0 10px}.yoast-dashboard .period{color:#555;font-size:.8em;font-weight:400;font-style:italic}.yoast-data-table table.dataTable thead .sorting,.yoast-data-table table.dataTable thead .sorting_asc,.yoast-data-table table.dataTable thead .sorting_desc{border-color:#d3d3d3}.yoast-data-table table.dataTable.no-footer{border-bottom:none}
 
assets/css/yoast_ga_styles.css DELETED
@@ -1,232 +0,0 @@
1
- h2#yoast_ga_title {
2
- padding: 9px 15px 4px 0;
3
- font-size: 23px;
4
- font-weight: 400;
5
- line-height: 29px;
6
- }
7
-
8
- .nav-tab-wrapper {
9
- margin-bottom: 20px;
10
- }
11
-
12
- .gatab {
13
- display: none;
14
- }
15
-
16
- .gatab.active {
17
- display: block;
18
- padding: 0.5em 0.9em;
19
- border: 1px solid #ddd;
20
- border-radius: 0 3px 3px 3px;
21
- background-color: #fff;
22
- }
23
-
24
- .tabwrapper .gatab {
25
- padding: 0;
26
- border: none;
27
- background: none;
28
- }
29
-
30
- .tabwrapper .gatab h2 {
31
- padding: 9px 15px 4px 0;
32
- font-size: 23px;
33
- font-weight: 400;
34
- }
35
-
36
- .ga-form-submit {
37
- margin-top: 20px;
38
- }
39
-
40
- .ga-form-label-left {
41
- float: left;
42
- width: 250px;
43
- margin: 0 0 0 5px;
44
- font-size: 14px;
45
- font-weight: bold;
46
- }
47
-
48
- #yoast-ga-displayfeatures-warning {
49
- float: right;
50
- width: 63%;
51
- color: red;
52
- }
53
-
54
- .ga-form-input {
55
- margin-top: 10px;
56
- margin-bottom: 10px;
57
- }
58
-
59
- #yoast-ga-wrapper {
60
- display: table;
61
- width: auto;
62
- max-width: 1150px;
63
- }
64
-
65
- .yoast-ga-content {
66
- display: table-cell;
67
- min-width: 850px;
68
- height: 500px;
69
- margin: 0;
70
- padding: 0;
71
- vertical-align: top;
72
- }
73
-
74
- .yoast-ga-banners {
75
- display: table-cell;
76
- width: 261px;
77
- height: 500px;
78
- margin: 0;
79
- padding: 0;
80
- padding: 20px;
81
- vertical-align: top;
82
- }
83
-
84
- .ga-form-input {
85
- display: table;
86
- margin-bottom: 20px;
87
- }
88
-
89
- .ga-form-table {
90
- display: table-cell;
91
- }
92
-
93
- .ga-form-description {
94
- display: block;
95
- float: right;
96
- max-width: 325px;
97
- color: #999;
98
- }
99
-
100
- p.ga-topdescription {
101
- max-width: 600px;
102
- }
103
-
104
- #ga-promote,
105
- .ga-promote {
106
- max-width: 600px;
107
- padding-left: 10px;
108
- border: 1px solid #ccc;
109
- background-color: #fff;
110
- }
111
-
112
- .ga-promote {
113
- margin-bottom: 10px;
114
- }
115
-
116
- #ga-promote p,
117
- .ga-promote p {
118
- margin: 0;
119
- padding: 1em 1em 1em 0;
120
- }
121
-
122
- #yoast-ga-form-settings input[type="text"] {
123
- width: 325px;
124
- }
125
-
126
- #yoast-ga-form-settings #oauth_code {
127
- padding: 20px;
128
- }
129
-
130
- #yoast-ga-form-settings #oauth_code div {
131
- margin: 0 0 0 5px;
132
- }
133
-
134
- #yoast-ga-form-settings #oauth_code input[type="text"] {
135
- width: 275px;
136
- }
137
-
138
- .ga-form .chosen-search input[type="text"] {
139
- width: 100% !important;
140
- }
141
-
142
- .yoast-ga-content .chosen-container {
143
- width: 325px !important;
144
- }
145
-
146
- #enter_ua {
147
- display: none;
148
- margin-top: 10px;
149
- padding-top: 10px;
150
- }
151
-
152
- #yoast-ga-form-text-settings-ga_general-manual_ua_code_field {
153
- margin-top: -30px;
154
- }
155
-
156
- select.ga-multiple {
157
- width: 300px;
158
- height: 150px !important;
159
- }
160
-
161
- .wpseotab .extension {
162
- float: left;
163
- box-sizing: border-box;
164
- width: 350px;
165
- height: 230px;
166
- margin: 10px 20px 10px 0;
167
- border: 1px solid #ccc;
168
- }
169
-
170
- .wpseotab .extension p {
171
- margin: 0;
172
- padding: 10px;
173
- }
174
-
175
- .wpseotab .extension h3 {
176
- box-sizing: border-box;
177
- height: 110px;
178
- margin: 0;
179
- padding: 20px 10px 0 120px;
180
- border-bottom: 1px solid #ccc;
181
- background: #fff no-repeat left 10px;
182
- background-repeat: no-repeat;
183
- background-size: 84px 84px;
184
- background-position-x: 5%;
185
- }
186
-
187
- .wpseotab .extension button.installed {
188
- border-color: #00a000;
189
- background-color: #00a000;
190
- cursor: default;
191
- }
192
-
193
- .wpseotab .extension .button-primary.activate-link {
194
- border-color: #f06000;
195
- background-color: #f18500;
196
- box-shadow: none;
197
- text-shadow: none;
198
- }
199
-
200
- .extension a {
201
- text-decoration: none;
202
- }
203
-
204
- .ecommerce h3 {
205
- background-image: url(../img/eComm_130x100.png) !important;
206
- background-repeat: no-repeat;
207
- background-size: 84px 84px;
208
- background-position-x: 5%;
209
- }
210
-
211
- .ga_premium h3 {
212
- background-image: url(../img/ga-premium-banner.png) !important;
213
- background-repeat: no-repeat;
214
- background-size: 84px 84px;
215
- background-position-x: 5%;
216
- }
217
-
218
- #ga-debug-info h3 {
219
- height: 30px;
220
- margin-top: 10px;
221
- padding-left: 16px;
222
- font-size: 14px;
223
- }
224
-
225
- .yoast_help {
226
- margin: 2px 5px 0 5px;
227
- }
228
-
229
- #enter_ua div {
230
- display: inline-block;
231
- margin: 0;
232
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/yoast_ga_styles.min.css DELETED
@@ -1 +0,0 @@
1
- h2#yoast_ga_title{padding:9px 15px 4px 0;font-size:23px;font-weight:400;line-height:29px}.nav-tab-wrapper{margin-bottom:20px}.gatab{display:none}.gatab.active{display:block;padding:.5em .9em;border:1px solid #ddd;border-radius:0 3px 3px;background-color:#fff}.tabwrapper .gatab{padding:0;border:none;background:0 0}.tabwrapper .gatab h2{padding:9px 15px 4px 0;font-size:23px;font-weight:400}.ga-form-submit{margin-top:20px}.ga-form-label-left{float:left;width:250px;margin:0 0 0 5px;font-size:14px;font-weight:700}#yoast-ga-displayfeatures-warning{float:right;width:63%;color:red}.ga-form-input{margin-top:10px}#yoast-ga-wrapper{display:table;width:auto;max-width:1150px}.yoast-ga-banners,.yoast-ga-content{display:table-cell;height:500px;margin:0;vertical-align:top}.yoast-ga-content{min-width:850px;padding:0}.yoast-ga-banners{width:261px;padding:20px}.ga-form-input{display:table;margin-bottom:20px}.ga-form-table{display:table-cell}.ga-form-description{display:block;float:right;max-width:325px;color:#999}p.ga-topdescription{max-width:600px}#ga-promote,.ga-promote{max-width:600px;padding-left:10px;border:1px solid #ccc;background-color:#fff}.ga-promote{margin-bottom:10px}#ga-promote p,.ga-promote p{margin:0;padding:1em 1em 1em 0}#yoast-ga-form-settings input[type=text]{width:325px}#yoast-ga-form-settings #oauth_code{padding:20px}#yoast-ga-form-settings #oauth_code div{margin:0 0 0 5px}#yoast-ga-form-settings #oauth_code input[type=text]{width:275px}.ga-form .chosen-search input[type=text]{width:100%!important}.yoast-ga-content .chosen-container{width:325px!important}#enter_ua{display:none;margin-top:10px;padding-top:10px}#yoast-ga-form-text-settings-ga_general-manual_ua_code_field{margin-top:-30px}select.ga-multiple{width:300px;height:150px!important}.wpseotab .extension{float:left;box-sizing:border-box;width:350px;height:230px;margin:10px 20px 10px 0;border:1px solid #ccc}.wpseotab .extension p{margin:0;padding:10px}.wpseotab .extension h3{box-sizing:border-box;height:110px;margin:0;padding:20px 10px 0 120px;border-bottom:1px solid #ccc;background:left 10px no-repeat #fff;background-size:84px 84px;background-position-x:5%}.ecommerce h3,.ga_premium h3{background-repeat:no-repeat;background-size:84px 84px;background-position-x:5%}.wpseotab .extension button.installed{border-color:#00a000;background-color:#00a000;cursor:default}.wpseotab .extension .button-primary.activate-link{border-color:#f06000;background-color:#f18500;box-shadow:none;text-shadow:none}.extension a{text-decoration:none}.ecommerce h3{background-image:url(../img/eComm_130x100.png)!important}.ga_premium h3{background-image:url(../img/ga-premium-banner.png)!important}#ga-debug-info h3{height:30px;margin-top:10px;padding-left:16px;font-size:14px}.yoast_help{margin:2px 5px 0}#enter_ua div{display:inline-block;margin:0}
 
assets/dependencies/chosen/chosen-sprite.png DELETED
Binary file
assets/dependencies/chosen/chosen-sprite@2x.png DELETED
Binary file
assets/dependencies/chosen/chosen.css DELETED
@@ -1,437 +0,0 @@
1
- /*!
2
- Chosen, a Select Box Enhancer for jQuery and Prototype
3
- by Patrick Filler for Harvest, http://getharvest.com
4
-
5
- Version 1.2.0
6
- Full source at https://github.com/harvesthq/chosen
7
- Copyright (c) 2011-2014 Harvest http://getharvest.com
8
-
9
- MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
- This file is generated by `grunt build`, do not edit it by hand.
11
- */
12
-
13
- /* @group Base */
14
- .chosen-container {
15
- position: relative;
16
- display: inline-block;
17
- vertical-align: middle;
18
- font-size: 13px;
19
- zoom: 1;
20
- *display: inline;
21
- -webkit-user-select: none;
22
- -moz-user-select: none;
23
- user-select: none;
24
- }
25
- .chosen-container * {
26
- -webkit-box-sizing: border-box;
27
- -moz-box-sizing: border-box;
28
- box-sizing: border-box;
29
- }
30
- .chosen-container .chosen-drop {
31
- position: absolute;
32
- top: 100%;
33
- left: -9999px;
34
- z-index: 1010;
35
- width: 100%;
36
- border: 1px solid #aaa;
37
- border-top: 0;
38
- background: #fff;
39
- box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
40
- }
41
- .chosen-container.chosen-with-drop .chosen-drop {
42
- left: 0;
43
- }
44
- .chosen-container a {
45
- cursor: pointer;
46
- }
47
-
48
- /* @end */
49
- /* @group Single Chosen */
50
- .chosen-container-single .chosen-single {
51
- position: relative;
52
- display: block;
53
- overflow: hidden;
54
- padding: 0 0 0 8px;
55
- height: 25px;
56
- border: 1px solid #aaa;
57
- border-radius: 5px;
58
- background-color: #fff;
59
- background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
60
- background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
61
- background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
62
- background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
63
- background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
64
- background-clip: padding-box;
65
- box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
66
- color: #444;
67
- text-decoration: none;
68
- white-space: nowrap;
69
- line-height: 24px;
70
- }
71
- .chosen-container-single .chosen-default {
72
- color: #999;
73
- }
74
- .chosen-container-single .chosen-single span {
75
- display: block;
76
- overflow: hidden;
77
- margin-right: 26px;
78
- text-overflow: ellipsis;
79
- white-space: nowrap;
80
- }
81
- .chosen-container-single .chosen-single-with-deselect span {
82
- margin-right: 38px;
83
- }
84
- .chosen-container-single .chosen-single abbr {
85
- position: absolute;
86
- top: 6px;
87
- right: 26px;
88
- display: block;
89
- width: 12px;
90
- height: 12px;
91
- background: url('chosen-sprite.png') -42px 1px no-repeat;
92
- font-size: 1px;
93
- }
94
- .chosen-container-single .chosen-single abbr:hover {
95
- background-position: -42px -10px;
96
- }
97
- .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
98
- background-position: -42px -10px;
99
- }
100
- .chosen-container-single .chosen-single div {
101
- position: absolute;
102
- top: 0;
103
- right: 0;
104
- display: block;
105
- width: 18px;
106
- height: 100%;
107
- }
108
- .chosen-container-single .chosen-single div b {
109
- display: block;
110
- width: 100%;
111
- height: 100%;
112
- background: url('chosen-sprite.png') no-repeat 0px 2px;
113
- }
114
- .chosen-container-single .chosen-search {
115
- position: relative;
116
- z-index: 1010;
117
- margin: 0;
118
- padding: 3px 4px;
119
- white-space: nowrap;
120
- }
121
- .chosen-container-single .chosen-search input[type="text"] {
122
- margin: 1px 0;
123
- padding: 4px 20px 4px 5px;
124
- width: 100%;
125
- height: auto;
126
- outline: 0;
127
- border: 1px solid #aaa;
128
- background: white url('chosen-sprite.png') no-repeat 100% -20px;
129
- background: url('chosen-sprite.png') no-repeat 100% -20px;
130
- font-size: 1em;
131
- font-family: sans-serif;
132
- line-height: normal;
133
- border-radius: 0;
134
- }
135
- .chosen-container-single .chosen-drop {
136
- margin-top: -1px;
137
- border-radius: 0 0 4px 4px;
138
- background-clip: padding-box;
139
- }
140
- .chosen-container-single.chosen-container-single-nosearch .chosen-search {
141
- position: absolute;
142
- left: -9999px;
143
- }
144
-
145
- /* @end */
146
- /* @group Results */
147
- .chosen-container .chosen-results {
148
- color: #444;
149
- position: relative;
150
- overflow-x: hidden;
151
- overflow-y: auto;
152
- margin: 0 4px 4px 0;
153
- padding: 0 0 0 4px;
154
- max-height: 240px;
155
- -webkit-overflow-scrolling: touch;
156
- }
157
- .chosen-container .chosen-results li {
158
- display: none;
159
- margin: 0;
160
- padding: 5px 6px;
161
- list-style: none;
162
- line-height: 15px;
163
- word-wrap: break-word;
164
- -webkit-touch-callout: none;
165
- }
166
- .chosen-container .chosen-results li.active-result {
167
- display: list-item;
168
- cursor: pointer;
169
- }
170
- .chosen-container .chosen-results li.disabled-result {
171
- display: list-item;
172
- color: #ccc;
173
- cursor: default;
174
- }
175
- .chosen-container .chosen-results li.highlighted {
176
- background-color: #3875d7;
177
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
178
- background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
179
- background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
180
- background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
181
- background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
182
- color: #fff;
183
- }
184
- .chosen-container .chosen-results li.no-results {
185
- color: #777;
186
- display: list-item;
187
- background: #f4f4f4;
188
- }
189
- .chosen-container .chosen-results li.group-result {
190
- display: list-item;
191
- font-weight: bold;
192
- cursor: default;
193
- }
194
- .chosen-container .chosen-results li.group-option {
195
- padding-left: 15px;
196
- }
197
- .chosen-container .chosen-results li em {
198
- font-style: normal;
199
- text-decoration: underline;
200
- }
201
-
202
- /* @end */
203
- /* @group Multi Chosen */
204
- .chosen-container-multi .chosen-choices {
205
- position: relative;
206
- overflow: hidden;
207
- margin: 0;
208
- padding: 0 5px;
209
- width: 100%;
210
- height: auto !important;
211
- height: 1%;
212
- border: 1px solid #aaa;
213
- background-color: #fff;
214
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
215
- background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
216
- background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
217
- background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
218
- background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
219
- cursor: text;
220
- }
221
- .chosen-container-multi .chosen-choices li {
222
- float: left;
223
- list-style: none;
224
- }
225
- .chosen-container-multi .chosen-choices li.search-field {
226
- margin: 0;
227
- padding: 0;
228
- white-space: nowrap;
229
- }
230
- .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
231
- margin: 1px 0;
232
- padding: 0;
233
- height: 25px;
234
- outline: 0;
235
- border: 0 !important;
236
- background: transparent !important;
237
- box-shadow: none;
238
- color: #999;
239
- font-size: 100%;
240
- font-family: sans-serif;
241
- line-height: normal;
242
- border-radius: 0;
243
- }
244
- .chosen-container-multi .chosen-choices li.search-choice {
245
- position: relative;
246
- margin: 3px 5px 3px 0;
247
- padding: 3px 20px 3px 5px;
248
- border: 1px solid #aaa;
249
- max-width: 100%;
250
- border-radius: 3px;
251
- background-color: #eeeeee;
252
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
253
- background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
254
- background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
255
- background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
256
- background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
257
- background-size: 100% 19px;
258
- background-repeat: repeat-x;
259
- background-clip: padding-box;
260
- box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
261
- color: #333;
262
- line-height: 13px;
263
- cursor: default;
264
- }
265
- .chosen-container-multi .chosen-choices li.search-choice span {
266
- word-wrap: break-word;
267
- }
268
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
269
- position: absolute;
270
- top: 4px;
271
- right: 3px;
272
- display: block;
273
- width: 12px;
274
- height: 12px;
275
- background: url('chosen-sprite.png') -42px 1px no-repeat;
276
- font-size: 1px;
277
- }
278
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
279
- background-position: -42px -10px;
280
- }
281
- .chosen-container-multi .chosen-choices li.search-choice-disabled {
282
- padding-right: 5px;
283
- border: 1px solid #ccc;
284
- background-color: #e4e4e4;
285
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
286
- background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
287
- background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
288
- background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
289
- background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
290
- color: #666;
291
- }
292
- .chosen-container-multi .chosen-choices li.search-choice-focus {
293
- background: #d4d4d4;
294
- }
295
- .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
296
- background-position: -42px -10px;
297
- }
298
- .chosen-container-multi .chosen-results {
299
- margin: 0;
300
- padding: 0;
301
- }
302
- .chosen-container-multi .chosen-drop .result-selected {
303
- display: list-item;
304
- color: #ccc;
305
- cursor: default;
306
- }
307
-
308
- /* @end */
309
- /* @group Active */
310
- .chosen-container-active .chosen-single {
311
- border: 1px solid #5897fb;
312
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
313
- }
314
- .chosen-container-active.chosen-with-drop .chosen-single {
315
- border: 1px solid #aaa;
316
- -moz-border-radius-bottomright: 0;
317
- border-bottom-right-radius: 0;
318
- -moz-border-radius-bottomleft: 0;
319
- border-bottom-left-radius: 0;
320
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
321
- background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
322
- background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
323
- background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
324
- background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
325
- box-shadow: 0 1px 0 #fff inset;
326
- }
327
- .chosen-container-active.chosen-with-drop .chosen-single div {
328
- border-left: none;
329
- background: transparent;
330
- }
331
- .chosen-container-active.chosen-with-drop .chosen-single div b {
332
- background-position: -18px 2px;
333
- }
334
- .chosen-container-active .chosen-choices {
335
- border: 1px solid #5897fb;
336
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
337
- }
338
- .chosen-container-active .chosen-choices li.search-field input[type="text"] {
339
- color: #222 !important;
340
- }
341
-
342
- /* @end */
343
- /* @group Disabled Support */
344
- .chosen-disabled {
345
- opacity: 0.5 !important;
346
- cursor: default;
347
- }
348
- .chosen-disabled .chosen-single {
349
- cursor: default;
350
- }
351
- .chosen-disabled .chosen-choices .search-choice .search-choice-close {
352
- cursor: default;
353
- }
354
-
355
- /* @end */
356
- /* @group Right to Left */
357
- .chosen-rtl {
358
- text-align: right;
359
- }
360
- .chosen-rtl .chosen-single {
361
- overflow: visible;
362
- padding: 0 8px 0 0;
363
- }
364
- .chosen-rtl .chosen-single span {
365
- margin-right: 0;
366
- margin-left: 26px;
367
- direction: rtl;
368
- }
369
- .chosen-rtl .chosen-single-with-deselect span {
370
- margin-left: 38px;
371
- }
372
- .chosen-rtl .chosen-single div {
373
- right: auto;
374
- left: 3px;
375
- }
376
- .chosen-rtl .chosen-single abbr {
377
- right: auto;
378
- left: 26px;
379
- }
380
- .chosen-rtl .chosen-choices li {
381
- float: right;
382
- }
383
- .chosen-rtl .chosen-choices li.search-field input[type="text"] {
384
- direction: rtl;
385
- }
386
- .chosen-rtl .chosen-choices li.search-choice {
387
- margin: 3px 5px 3px 0;
388
- padding: 3px 5px 3px 19px;
389
- }
390
- .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
391
- right: auto;
392
- left: 4px;
393
- }
394
- .chosen-rtl.chosen-container-single-nosearch .chosen-search,
395
- .chosen-rtl .chosen-drop {
396
- left: 9999px;
397
- }
398
- .chosen-rtl.chosen-container-single .chosen-results {
399
- margin: 0 0 4px 4px;
400
- padding: 0 4px 0 0;
401
- }
402
- .chosen-rtl .chosen-results li.group-option {
403
- padding-right: 15px;
404
- padding-left: 0;
405
- }
406
- .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
407
- border-right: none;
408
- }
409
- .chosen-rtl .chosen-search input[type="text"] {
410
- padding: 4px 5px 4px 20px;
411
- background: white url('chosen-sprite.png') no-repeat -30px -20px;
412
- background: url('chosen-sprite.png') no-repeat -30px -20px;
413
- direction: rtl;
414
- }
415
- .chosen-rtl.chosen-container-single .chosen-single div b {
416
- background-position: 6px 2px;
417
- }
418
- .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
419
- background-position: -12px 2px;
420
- }
421
-
422
- /* @end */
423
- /* @group Retina compatibility */
424
- @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
425
- .chosen-rtl .chosen-search input[type="text"],
426
- .chosen-container-single .chosen-single abbr,
427
- .chosen-container-single .chosen-single div b,
428
- .chosen-container-single .chosen-search input[type="text"],
429
- .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
430
- .chosen-container .chosen-results-scroll-down span,
431
- .chosen-container .chosen-results-scroll-up span {
432
- background-image: url('chosen-sprite@2x.png') !important;
433
- background-size: 52px 37px !important;
434
- background-repeat: no-repeat !important;
435
- }
436
- }
437
- /* @end */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/dependencies/chosen/chosen.jquery.min.js DELETED
@@ -1,2 +0,0 @@
1
- /* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2
- !function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.text,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+"</em>"+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+"<em>"+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d instanceof Chosen?d.destroy():d instanceof Chosen||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("touchstart.chosen",function(b){a.container_mousedown(b)}),this.container.bind("touchend.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=a.originalEvent.deltaY||-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
 
 
assets/dependencies/chosen/chosen.min.css DELETED
@@ -1,3 +0,0 @@
1
- /* Chosen v1.2.0 | (c) 2011-2014 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2
-
3
- .chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:25px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;padding:0 5px;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
 
 
 
assets/dependencies/chosen/index.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- //Nothing to see here
3
-
4
- header( 'HTTP/1.0 403 Forbidden' );
 
 
 
 
assets/dependencies/datatables/css/jquery.dataTables.css DELETED
@@ -1,450 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/dependencies/datatables/css/jquery.dataTables.min.css DELETED
@@ -1 +0,0 @@
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}}
 
assets/dependencies/datatables/images/Sorting icons.psd DELETED
Binary file
assets/dependencies/datatables/images/back_disabled.png DELETED
Binary file
assets/dependencies/datatables/images/back_enabled.png DELETED
Binary file
assets/dependencies/datatables/images/back_enabled_hover.png DELETED
Binary file
assets/dependencies/datatables/images/favicon.ico DELETED
Binary file
assets/dependencies/datatables/images/forward_disabled.png DELETED
Binary file
assets/dependencies/datatables/images/forward_enabled.png DELETED
Binary file
assets/dependencies/datatables/images/forward_enabled_hover.png DELETED
Binary file
assets/dependencies/datatables/images/sort_asc.png DELETED
Binary file
assets/dependencies/datatables/images/sort_asc_disabled.png DELETED
Binary file
assets/dependencies/datatables/images/sort_both.png DELETED
Binary file
assets/dependencies/datatables/images/sort_desc.png DELETED
Binary file
assets/dependencies/datatables/images/sort_desc_disabled.png DELETED
Binary file
assets/dependencies/datatables/js/jquery.dataTables.js DELETED
@@ -1,15095 +0,0 @@
1
- /*! DataTables 1.10.8
2
- * ©2008-2014 SpryMedia Ltd - datatables.net/license
3
- */
4
-
5
- /**
6
- * @summary DataTables
7
- * @description Paginate, search and order HTML tables
8
- * @version 1.10.8
9
- * @file jquery.dataTables.js
10
- * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
- * @contact www.sprymedia.co.uk/contact
12
- * @copyright Copyright 2008-2014 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,_fnScrollBarWidth,_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
- var browser = settings.oBrowser;
518
-
519
- // Scrolling feature / quirks detection
520
- var n = $('<div/>')
521
- .css( {
522
- position: 'fixed',
523
- top: 0,
524
- left: 0,
525
- height: 1,
526
- width: 1,
527
- overflow: 'hidden'
528
- } )
529
- .append(
530
- $('<div/>')
531
- .css( {
532
- position: 'absolute',
533
- top: 1,
534
- left: 1,
535
- width: 100,
536
- overflow: 'scroll'
537
- } )
538
- .append(
539
- $('<div class="test"/>')
540
- .css( {
541
- width: '100%',
542
- height: 10
543
- } )
544
- )
545
- )
546
- .appendTo( 'body' );
547
-
548
- var test = n.find('.test');
549
-
550
- // IE6/7 will oversize a width 100% element inside a scrolling element, to
551
- // include the width of the scrollbar, while other browsers ensure the inner
552
- // element is contained without forcing scrolling
553
- browser.bScrollOversize = test[0].offsetWidth === 100;
554
-
555
- // In rtl text layout, some browsers (most, but not all) will place the
556
- // scrollbar on the left, rather than the right.
557
- browser.bScrollbarLeft = Math.round( test.offset().left ) !== 1;
558
-
559
- // IE8- don't provide height and width for getBoundingClientRect
560
- browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
561
-
562
- n.remove();
563
- }
564
-
565
-
566
- /**
567
- * Array.prototype reduce[Right] method, used for browsers which don't support
568
- * JS 1.6. Done this way to reduce code size, since we iterate either way
569
- * @param {object} settings dataTables settings object
570
- * @memberof DataTable#oApi
571
- */
572
- function _fnReduce ( that, fn, init, start, end, inc )
573
- {
574
- var
575
- i = start,
576
- value,
577
- isSet = false;
578
-
579
- if ( init !== undefined ) {
580
- value = init;
581
- isSet = true;
582
- }
583
-
584
- while ( i !== end ) {
585
- if ( ! that.hasOwnProperty(i) ) {
586
- continue;
587
- }
588
-
589
- value = isSet ?
590
- fn( value, that[i], i, that ) :
591
- that[i];
592
-
593
- isSet = true;
594
- i += inc;
595
- }
596
-
597
- return value;
598
- }
599
-
600
- /**
601
- * Add a column to the list used for the table with default values
602
- * @param {object} oSettings dataTables settings object
603
- * @param {node} nTh The th element for this column
604
- * @memberof DataTable#oApi
605
- */
606
- function _fnAddColumn( oSettings, nTh )
607
- {
608
- // Add column to aoColumns array
609
- var oDefaults = DataTable.defaults.column;
610
- var iCol = oSettings.aoColumns.length;
611
- var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
612
- "nTh": nTh ? nTh : document.createElement('th'),
613
- "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
614
- "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
615
- "mData": oDefaults.mData ? oDefaults.mData : iCol,
616
- idx: iCol
617
- } );
618
- oSettings.aoColumns.push( oCol );
619
-
620
- // Add search object for column specific search. Note that the `searchCols[ iCol ]`
621
- // passed into extend can be undefined. This allows the user to give a default
622
- // with only some of the parameters defined, and also not give a default
623
- var searchCols = oSettings.aoPreSearchCols;
624
- searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
625
-
626
- // Use the default column options function to initialise classes etc
627
- _fnColumnOptions( oSettings, iCol, $(nTh).data() );
628
- }
629
-
630
-
631
- /**
632
- * Apply options for a column
633
- * @param {object} oSettings dataTables settings object
634
- * @param {int} iCol column index to consider
635
- * @param {object} oOptions object with sType, bVisible and bSearchable etc
636
- * @memberof DataTable#oApi
637
- */
638
- function _fnColumnOptions( oSettings, iCol, oOptions )
639
- {
640
- var oCol = oSettings.aoColumns[ iCol ];
641
- var oClasses = oSettings.oClasses;
642
- var th = $(oCol.nTh);
643
-
644
- // Try to get width information from the DOM. We can't get it from CSS
645
- // as we'd need to parse the CSS stylesheet. `width` option can override
646
- if ( ! oCol.sWidthOrig ) {
647
- // Width attribute
648
- oCol.sWidthOrig = th.attr('width') || null;
649
-
650
- // Style attribute
651
- var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
652
- if ( t ) {
653
- oCol.sWidthOrig = t[1];
654
- }
655
- }
656
-
657
- /* User specified column options */
658
- if ( oOptions !== undefined && oOptions !== null )
659
- {
660
- // Backwards compatibility
661
- _fnCompatCols( oOptions );
662
-
663
- // Map camel case parameters to their Hungarian counterparts
664
- _fnCamelToHungarian( DataTable.defaults.column, oOptions );
665
-
666
- /* Backwards compatibility for mDataProp */
667
- if ( oOptions.mDataProp !== undefined && !oOptions.mData )
668
- {
669
- oOptions.mData = oOptions.mDataProp;
670
- }
671
-
672
- if ( oOptions.sType )
673
- {
674
- oCol._sManualType = oOptions.sType;
675
- }
676
-
677
- // `class` is a reserved word in Javascript, so we need to provide
678
- // the ability to use a valid name for the camel case input
679
- if ( oOptions.className && ! oOptions.sClass )
680
- {
681
- oOptions.sClass = oOptions.className;
682
- }
683
-
684
- $.extend( oCol, oOptions );
685
- _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
686
-
687
- /* iDataSort to be applied (backwards compatibility), but aDataSort will take
688
- * priority if defined
689
- */
690
- if ( oOptions.iDataSort !== undefined )
691
- {
692
- oCol.aDataSort = [ oOptions.iDataSort ];
693
- }
694
- _fnMap( oCol, oOptions, "aDataSort" );
695
- }
696
-
697
- /* Cache the data get and set functions for speed */
698
- var mDataSrc = oCol.mData;
699
- var mData = _fnGetObjectDataFn( mDataSrc );
700
- var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
701
-
702
- var attrTest = function( src ) {
703
- return typeof src === 'string' && src.indexOf('@') !== -1;
704
- };
705
- oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
706
- attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
707
- );
708
-
709
- oCol.fnGetData = function (rowData, type, meta) {
710
- var innerData = mData( rowData, type, undefined, meta );
711
-
712
- return mRender && type ?
713
- mRender( innerData, type, rowData, meta ) :
714
- innerData;
715
- };
716
- oCol.fnSetData = function ( rowData, val, meta ) {
717
- return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
718
- };
719
-
720
- // Indicate if DataTables should read DOM data as an object or array
721
- // Used in _fnGetRowElements
722
- if ( typeof mDataSrc !== 'number' ) {
723
- oSettings._rowReadObject = true;
724
- }
725
-
726
- /* Feature sorting overrides column specific when off */
727
- if ( !oSettings.oFeatures.bSort )
728
- {
729
- oCol.bSortable = false;
730
- th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
731
- }
732
-
733
- /* Check that the class assignment is correct for sorting */
734
- var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
735
- var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
736
- if ( !oCol.bSortable || (!bAsc && !bDesc) )
737
- {
738
- oCol.sSortingClass = oClasses.sSortableNone;
739
- oCol.sSortingClassJUI = "";
740
- }
741
- else if ( bAsc && !bDesc )
742
- {
743
- oCol.sSortingClass = oClasses.sSortableAsc;
744
- oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
745
- }
746
- else if ( !bAsc && bDesc )
747
- {
748
- oCol.sSortingClass = oClasses.sSortableDesc;
749
- oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
750
- }
751
- else
752
- {
753
- oCol.sSortingClass = oClasses.sSortable;
754
- oCol.sSortingClassJUI = oClasses.sSortJUI;
755
- }
756
- }
757
-
758
-
759
- /**
760
- * Adjust the table column widths for new data. Note: you would probably want to
761
- * do a redraw after calling this function!
762
- * @param {object} settings dataTables settings object
763
- * @memberof DataTable#oApi
764
- */
765
- function _fnAdjustColumnSizing ( settings )
766
- {
767
- /* Not interested in doing column width calculation if auto-width is disabled */
768
- if ( settings.oFeatures.bAutoWidth !== false )
769
- {
770
- var columns = settings.aoColumns;
771
-
772
- _fnCalculateColumnWidths( settings );
773
- for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
774
- {
775
- columns[i].nTh.style.width = columns[i].sWidth;
776
- }
777
- }
778
-
779
- var scroll = settings.oScroll;
780
- if ( scroll.sY !== '' || scroll.sX !== '')
781
- {
782
- _fnScrollDraw( settings );
783
- }
784
-
785
- _fnCallbackFire( settings, null, 'column-sizing', [settings] );
786
- }
787
-
788
-
789
- /**
790
- * Covert the index of a visible column to the index in the data array (take account
791
- * of hidden columns)
792
- * @param {object} oSettings dataTables settings object
793
- * @param {int} iMatch Visible column index to lookup
794
- * @returns {int} i the data index
795
- * @memberof DataTable#oApi
796
- */
797
- function _fnVisibleToColumnIndex( oSettings, iMatch )
798
- {
799
- var aiVis = _fnGetColumns( oSettings, 'bVisible' );
800
-
801
- return typeof aiVis[iMatch] === 'number' ?
802
- aiVis[iMatch] :
803
- null;
804
- }
805
-
806
-
807
- /**
808
- * Covert the index of an index in the data array and convert it to the visible
809
- * column index (take account of hidden columns)
810
- * @param {int} iMatch Column index to lookup
811
- * @param {object} oSettings dataTables settings object
812
- * @returns {int} i the data index
813
- * @memberof DataTable#oApi
814
- */
815
- function _fnColumnIndexToVisible( oSettings, iMatch )
816
- {
817
- var aiVis = _fnGetColumns( oSettings, 'bVisible' );
818
- var iPos = $.inArray( iMatch, aiVis );
819
-
820
- return iPos !== -1 ? iPos : null;
821
- }
822
-
823
-
824
- /**
825
- * Get the number of visible columns
826
- * @param {object} oSettings dataTables settings object
827
- * @returns {int} i the number of visible columns
828
- * @memberof DataTable#oApi
829
- */
830
- function _fnVisbleColumns( oSettings )
831
- {
832
- return _fnGetColumns( oSettings, 'bVisible' ).length;
833
- }
834
-
835
-
836
- /**
837
- * Get an array of column indexes that match a given property
838
- * @param {object} oSettings dataTables settings object
839
- * @param {string} sParam Parameter in aoColumns to look for - typically
840
- * bVisible or bSearchable
841
- * @returns {array} Array of indexes with matched properties
842
- * @memberof DataTable#oApi
843
- */
844
- function _fnGetColumns( oSettings, sParam )
845
- {
846
- var a = [];
847
-
848
- $.map( oSettings.aoColumns, function(val, i) {
849
- if ( val[sParam] ) {
850
- a.push( i );
851
- }
852
- } );
853
-
854
- return a;
855
- }
856
-
857
-
858
- /**
859
- * Calculate the 'type' of a column
860
- * @param {object} settings dataTables settings object
861
- * @memberof DataTable#oApi
862
- */
863
- function _fnColumnTypes ( settings )
864
- {
865
- var columns = settings.aoColumns;
866
- var data = settings.aoData;
867
- var types = DataTable.ext.type.detect;
868
- var i, ien, j, jen, k, ken;
869
- var col, cell, detectedType, cache;
870
-
871
- // For each column, spin over the
872
- for ( i=0, ien=columns.length ; i<ien ; i++ ) {
873
- col = columns[i];
874
- cache = [];
875
-
876
- if ( ! col.sType && col._sManualType ) {
877
- col.sType = col._sManualType;
878
- }
879
- else if ( ! col.sType ) {
880
- for ( j=0, jen=types.length ; j<jen ; j++ ) {
881
- for ( k=0, ken=data.length ; k<ken ; k++ ) {
882
- // Use a cache array so we only need to get the type data
883
- // from the formatter once (when using multiple detectors)
884
- if ( cache[k] === undefined ) {
885
- cache[k] = _fnGetCellData( settings, k, i, 'type' );
886
- }
887
-
888
- detectedType = types[j]( cache[k], settings );
889
-
890
- // If null, then this type can't apply to this column, so
891
- // rather than testing all cells, break out. There is an
892
- // exception for the last type which is `html`. We need to
893
- // scan all rows since it is possible to mix string and HTML
894
- // types
895
- if ( ! detectedType && j !== types.length-1 ) {
896
- break;
897
- }
898
-
899
- // Only a single match is needed for html type since it is
900
- // bottom of the pile and very similar to string
901
- if ( detectedType === 'html' ) {
902
- break;
903
- }
904
- }
905
-
906
- // Type is valid for all data points in the column - use this
907
- // type
908
- if ( detectedType ) {
909
- col.sType = detectedType;
910
- break;
911
- }
912
- }
913
-
914
- // Fall back - if no type was detected, always use string
915
- if ( ! col.sType ) {
916
- col.sType = 'string';
917
- }
918
- }
919
- }
920
- }
921
-
922
-
923
- /**
924
- * Take the column definitions and static columns arrays and calculate how
925
- * they relate to column indexes. The callback function will then apply the
926
- * definition found for a column to a suitable configuration object.
927
- * @param {object} oSettings dataTables settings object
928
- * @param {array} aoColDefs The aoColumnDefs array that is to be applied
929
- * @param {array} aoCols The aoColumns array that defines columns individually
930
- * @param {function} fn Callback function - takes two parameters, the calculated
931
- * column index and the definition for that column.
932
- * @memberof DataTable#oApi
933
- */
934
- function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
935
- {
936
- var i, iLen, j, jLen, k, kLen, def;
937
- var columns = oSettings.aoColumns;
938
-
939
- // Column definitions with aTargets
940
- if ( aoColDefs )
941
- {
942
- /* Loop over the definitions array - loop in reverse so first instance has priority */
943
- for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
944
- {
945
- def = aoColDefs[i];
946
-
947
- /* Each definition can target multiple columns, as it is an array */
948
- var aTargets = def.targets !== undefined ?
949
- def.targets :
950
- def.aTargets;
951
-
952
- if ( ! $.isArray( aTargets ) )
953
- {
954
- aTargets = [ aTargets ];
955
- }
956
-
957
- for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
958
- {
959
- if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
960
- {
961
- /* Add columns that we don't yet know about */
962
- while( columns.length <= aTargets[j] )
963
- {
964
- _fnAddColumn( oSettings );
965
- }
966
-
967
- /* Integer, basic index */
968
- fn( aTargets[j], def );
969
- }
970
- else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
971
- {
972
- /* Negative integer, right to left column counting */
973
- fn( columns.length+aTargets[j], def );
974
- }
975
- else if ( typeof aTargets[j] === 'string' )
976
- {
977
- /* Class name matching on TH element */
978
- for ( k=0, kLen=columns.length ; k<kLen ; k++ )
979
- {
980
- if ( aTargets[j] == "_all" ||
981
- $(columns[k].nTh).hasClass( aTargets[j] ) )
982
- {
983
- fn( k, def );
984
- }
985
- }
986
- }
987
- }
988
- }
989
- }
990
-
991
- // Statically defined columns array
992
- if ( aoCols )
993
- {
994
- for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
995
- {
996
- fn( i, aoCols[i] );
997
- }
998
- }
999
- }
1000
-
1001
- /**
1002
- * Add a data array to the table, creating DOM node etc. This is the parallel to
1003
- * _fnGatherData, but for adding rows from a Javascript source, rather than a
1004
- * DOM source.
1005
- * @param {object} oSettings dataTables settings object
1006
- * @param {array} aData data array to be added
1007
- * @param {node} [nTr] TR element to add to the table - optional. If not given,
1008
- * DataTables will create a row automatically
1009
- * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1010
- * if nTr is.
1011
- * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
1012
- * @memberof DataTable#oApi
1013
- */
1014
- function _fnAddData ( oSettings, aDataIn, nTr, anTds )
1015
- {
1016
- /* Create the object for storing information about this new row */
1017
- var iRow = oSettings.aoData.length;
1018
- var oData = $.extend( true, {}, DataTable.models.oRow, {
1019
- src: nTr ? 'dom' : 'data',
1020
- idx: iRow
1021
- } );
1022
-
1023
- oData._aData = aDataIn;
1024
- oSettings.aoData.push( oData );
1025
-
1026
- /* Create the cells */
1027
- var nTd, sThisType;
1028
- var columns = oSettings.aoColumns;
1029
- for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
1030
- {
1031
- // When working with a row, the data source object must be populated. In
1032
- // all other cases, the data source object is already populated, so we
1033
- // don't overwrite it, which might break bindings etc
1034
- if ( nTr ) {
1035
- _fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
1036
- }
1037
- columns[i].sType = null;
1038
- }
1039
-
1040
- /* Add to the display array */
1041
- oSettings.aiDisplayMaster.push( iRow );
1042
-
1043
- var id = oSettings.rowIdFn( aDataIn );
1044
- if ( id !== undefined ) {
1045
- oSettings.aIds[ id ] = oData;
1046
- }
1047
-
1048
- /* Create the DOM information, or register it if already present */
1049
- if ( nTr || ! oSettings.oFeatures.bDeferRender )
1050
- {
1051
- _fnCreateTr( oSettings, iRow, nTr, anTds );
1052
- }
1053
-
1054
- return iRow;
1055
- }
1056
-
1057
-
1058
- /**
1059
- * Add one or more TR elements to the table. Generally we'd expect to
1060
- * use this for reading data from a DOM sourced table, but it could be
1061
- * used for an TR element. Note that if a TR is given, it is used (i.e.
1062
- * it is not cloned).
1063
- * @param {object} settings dataTables settings object
1064
- * @param {array|node|jQuery} trs The TR element(s) to add to the table
1065
- * @returns {array} Array of indexes for the added rows
1066
- * @memberof DataTable#oApi
1067
- */
1068
- function _fnAddTr( settings, trs )
1069
- {
1070
- var row;
1071
-
1072
- // Allow an individual node to be passed in
1073
- if ( ! (trs instanceof $) ) {
1074
- trs = $(trs);
1075
- }
1076
-
1077
- return trs.map( function (i, el) {
1078
- row = _fnGetRowElements( settings, el );
1079
- return _fnAddData( settings, row.data, el, row.cells );
1080
- } );
1081
- }
1082
-
1083
-
1084
- /**
1085
- * Take a TR element and convert it to an index in aoData
1086
- * @param {object} oSettings dataTables settings object
1087
- * @param {node} n the TR element to find
1088
- * @returns {int} index if the node is found, null if not
1089
- * @memberof DataTable#oApi
1090
- */
1091
- function _fnNodeToDataIndex( oSettings, n )
1092
- {
1093
- return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
1094
- }
1095
-
1096
-
1097
- /**
1098
- * Take a TD element and convert it into a column data index (not the visible index)
1099
- * @param {object} oSettings dataTables settings object
1100
- * @param {int} iRow The row number the TD/TH can be found in
1101
- * @param {node} n The TD/TH element to find
1102
- * @returns {int} index if the node is found, -1 if not
1103
- * @memberof DataTable#oApi
1104
- */
1105
- function _fnNodeToColumnIndex( oSettings, iRow, n )
1106
- {
1107
- return $.inArray( n, oSettings.aoData[ iRow ].anCells );
1108
- }
1109
-
1110
-
1111
- /**
1112
- * Get the data for a given cell from the internal cache, taking into account data mapping
1113
- * @param {object} settings dataTables settings object
1114
- * @param {int} rowIdx aoData row id
1115
- * @param {int} colIdx Column index
1116
- * @param {string} type data get type ('display', 'type' 'filter' 'sort')
1117
- * @returns {*} Cell data
1118
- * @memberof DataTable#oApi
1119
- */
1120
- function _fnGetCellData( settings, rowIdx, colIdx, type )
1121
- {
1122
- var draw = settings.iDraw;
1123
- var col = settings.aoColumns[colIdx];
1124
- var rowData = settings.aoData[rowIdx]._aData;
1125
- var defaultContent = col.sDefaultContent;
1126
- var cellData = col.fnGetData( rowData, type, {
1127
- settings: settings,
1128
- row: rowIdx,
1129
- col: colIdx
1130
- } );
1131
-
1132
- if ( cellData === undefined ) {
1133
- if ( settings.iDrawError != draw && defaultContent === null ) {
1134
- _fnLog( settings, 0, "Requested unknown parameter "+
1135
- (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
1136
- " for row "+rowIdx, 4 );
1137
- settings.iDrawError = draw;
1138
- }
1139
- return defaultContent;
1140
- }
1141
-
1142
- /* When the data source is null, we can use default column data */
1143
- if ( (cellData === rowData || cellData === null) && defaultContent !== null ) {
1144
- cellData = defaultContent;
1145
- }
1146
- else if ( typeof cellData === 'function' ) {
1147
- // If the data source is a function, then we run it and use the return,
1148
- // executing in the scope of the data object (for instances)
1149
- return cellData.call( rowData );
1150
- }
1151
-
1152
- if ( cellData === null && type == 'display' ) {
1153
- return '';
1154
- }
1155
- return cellData;
1156
- }
1157
-
1158
-
1159
- /**
1160
- * Set the value for a specific cell, into the internal data cache
1161
- * @param {object} settings dataTables settings object
1162
- * @param {int} rowIdx aoData row id
1163
- * @param {int} colIdx Column index
1164
- * @param {*} val Value to set
1165
- * @memberof DataTable#oApi
1166
- */
1167
- function _fnSetCellData( settings, rowIdx, colIdx, val )
1168
- {
1169
- var col = settings.aoColumns[colIdx];
1170
- var rowData = settings.aoData[rowIdx]._aData;
1171
-
1172
- col.fnSetData( rowData, val, {
1173
- settings: settings,
1174
- row: rowIdx,
1175
- col: colIdx
1176
- } );
1177
- }
1178
-
1179
-
1180
- // Private variable that is used to match action syntax in the data property object
1181
- var __reArray = /\[.*?\]$/;
1182
- var __reFn = /\(\)$/;
1183
-
1184
- /**
1185
- * Split string on periods, taking into account escaped periods
1186
- * @param {string} str String to split
1187
- * @return {array} Split string
1188
- */
1189
- function _fnSplitObjNotation( str )
1190
- {
1191
- return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
1192
- return s.replace(/\\./g, '.');
1193
- } );
1194
- }
1195
-
1196
-
1197
- /**
1198
- * Return a function that can be used to get data from a source object, taking
1199
- * into account the ability to use nested objects as a source
1200
- * @param {string|int|function} mSource The data source for the object
1201
- * @returns {function} Data get function
1202
- * @memberof DataTable#oApi
1203
- */
1204
- function _fnGetObjectDataFn( mSource )
1205
- {
1206
- if ( $.isPlainObject( mSource ) )
1207
- {
1208
- /* Build an object of get functions, and wrap them in a single call */
1209
- var o = {};
1210
- $.each( mSource, function (key, val) {
1211
- if ( val ) {
1212
- o[key] = _fnGetObjectDataFn( val );
1213
- }
1214
- } );
1215
-
1216
- return function (data, type, row, meta) {
1217
- var t = o[type] || o._;
1218
- return t !== undefined ?
1219
- t(data, type, row, meta) :
1220
- data;
1221
- };
1222
- }
1223
- else if ( mSource === null )
1224
- {
1225
- /* Give an empty string for rendering / sorting etc */
1226
- return function (data) { // type, row and meta also passed, but not used
1227
- return data;
1228
- };
1229
- }
1230
- else if ( typeof mSource === 'function' )
1231
- {
1232
- return function (data, type, row, meta) {
1233
- return mSource( data, type, row, meta );
1234
- };
1235
- }
1236
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1237
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1238
- {
1239
- /* If there is a . in the source string then the data source is in a
1240
- * nested object so we loop over the data for each level to get the next
1241
- * level down. On each loop we test for undefined, and if found immediately
1242
- * return. This allows entire objects to be missing and sDefaultContent to
1243
- * be used if defined, rather than throwing an error
1244
- */
1245
- var fetchData = function (data, type, src) {
1246
- var arrayNotation, funcNotation, out, innerSrc;
1247
-
1248
- if ( src !== "" )
1249
- {
1250
- var a = _fnSplitObjNotation( src );
1251
-
1252
- for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1253
- {
1254
- // Check if we are dealing with special notation
1255
- arrayNotation = a[i].match(__reArray);
1256
- funcNotation = a[i].match(__reFn);
1257
-
1258
- if ( arrayNotation )
1259
- {
1260
- // Array notation
1261
- a[i] = a[i].replace(__reArray, '');
1262
-
1263
- // Condition allows simply [] to be passed in
1264
- if ( a[i] !== "" ) {
1265
- data = data[ a[i] ];
1266
- }
1267
- out = [];
1268
-
1269
- // Get the remainder of the nested object to get
1270
- a.splice( 0, i+1 );
1271
- innerSrc = a.join('.');
1272
-
1273
- // Traverse each entry in the array getting the properties requested
1274
- for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
1275
- out.push( fetchData( data[j], type, innerSrc ) );
1276
- }
1277
-
1278
- // If a string is given in between the array notation indicators, that
1279
- // is used to join the strings together, otherwise an array is returned
1280
- var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
1281
- data = (join==="") ? out : out.join(join);
1282
-
1283
- // The inner call to fetchData has already traversed through the remainder
1284
- // of the source requested, so we exit from the loop
1285
- break;
1286
- }
1287
- else if ( funcNotation )
1288
- {
1289
- // Function call
1290
- a[i] = a[i].replace(__reFn, '');
1291
- data = data[ a[i] ]();
1292
- continue;
1293
- }
1294
-
1295
- if ( data === null || data[ a[i] ] === undefined )
1296
- {
1297
- return undefined;
1298
- }
1299
- data = data[ a[i] ];
1300
- }
1301
- }
1302
-
1303
- return data;
1304
- };
1305
-
1306
- return function (data, type) { // row and meta also passed, but not used
1307
- return fetchData( data, type, mSource );
1308
- };
1309
- }
1310
- else
1311
- {
1312
- /* Array or flat object mapping */
1313
- return function (data, type) { // row and meta also passed, but not used
1314
- return data[mSource];
1315
- };
1316
- }
1317
- }
1318
-
1319
-
1320
- /**
1321
- * Return a function that can be used to set data from a source object, taking
1322
- * into account the ability to use nested objects as a source
1323
- * @param {string|int|function} mSource The data source for the object
1324
- * @returns {function} Data set function
1325
- * @memberof DataTable#oApi
1326
- */
1327
- function _fnSetObjectDataFn( mSource )
1328
- {
1329
- if ( $.isPlainObject( mSource ) )
1330
- {
1331
- /* Unlike get, only the underscore (global) option is used for for
1332
- * setting data since we don't know the type here. This is why an object
1333
- * option is not documented for `mData` (which is read/write), but it is
1334
- * for `mRender` which is read only.
1335
- */
1336
- return _fnSetObjectDataFn( mSource._ );
1337
- }
1338
- else if ( mSource === null )
1339
- {
1340
- /* Nothing to do when the data source is null */
1341
- return function () {};
1342
- }
1343
- else if ( typeof mSource === 'function' )
1344
- {
1345
- return function (data, val, meta) {
1346
- mSource( data, 'set', val, meta );
1347
- };
1348
- }
1349
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1350
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1351
- {
1352
- /* Like the get, we need to get data from a nested object */
1353
- var setData = function (data, val, src) {
1354
- var a = _fnSplitObjNotation( src ), b;
1355
- var aLast = a[a.length-1];
1356
- var arrayNotation, funcNotation, o, innerSrc;
1357
-
1358
- for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
1359
- {
1360
- // Check if we are dealing with an array notation request
1361
- arrayNotation = a[i].match(__reArray);
1362
- funcNotation = a[i].match(__reFn);
1363
-
1364
- if ( arrayNotation )
1365
- {
1366
- a[i] = a[i].replace(__reArray, '');
1367
- data[ a[i] ] = [];
1368
-
1369
- // Get the remainder of the nested object to set so we can recurse
1370
- b = a.slice();
1371
- b.splice( 0, i+1 );
1372
- innerSrc = b.join('.');
1373
-
1374
- // Traverse each entry in the array setting the properties requested
1375
- for ( var j=0, jLen=val.length ; j<jLen ; j++ )
1376
- {
1377
- o = {};
1378
- setData( o, val[j], innerSrc );
1379
- data[ a[i] ].push( o );
1380
- }
1381
-
1382
- // The inner call to setData has already traversed through the remainder
1383
- // of the source and has set the data, thus we can exit here
1384
- return;
1385
- }
1386
- else if ( funcNotation )
1387
- {
1388
- // Function call
1389
- a[i] = a[i].replace(__reFn, '');
1390
- data = data[ a[i] ]( val );
1391
- }
1392
-
1393
- // If the nested object doesn't currently exist - since we are
1394
- // trying to set the value - create it
1395
- if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
1396
- {
1397
- data[ a[i] ] = {};
1398
- }
1399
- data = data[ a[i] ];
1400
- }
1401
-
1402
- // Last item in the input - i.e, the actual set
1403
- if ( aLast.match(__reFn ) )
1404
- {
1405
- // Function call
1406
- data = data[ aLast.replace(__reFn, '') ]( val );
1407
- }
1408
- else
1409
- {
1410
- // If array notation is used, we just want to strip it and use the property name
1411
- // and assign the value. If it isn't used, then we get the result we want anyway
1412
- data[ aLast.replace(__reArray, '') ] = val;
1413
- }
1414
- };
1415
-
1416
- return function (data, val) { // meta is also passed in, but not used
1417
- return setData( data, val, mSource );
1418
- };
1419
- }
1420
- else
1421
- {
1422
- /* Array or flat object mapping */
1423
- return function (data, val) { // meta is also passed in, but not used
1424
- data[mSource] = val;
1425
- };
1426
- }
1427
- }
1428
-
1429
-
1430
- /**
1431
- * Return an array with the full table data
1432
- * @param {object} oSettings dataTables settings object
1433
- * @returns array {array} aData Master data array
1434
- * @memberof DataTable#oApi
1435
- */
1436
- function _fnGetDataMaster ( settings )
1437
- {
1438
- return _pluck( settings.aoData, '_aData' );
1439
- }
1440
-
1441
-
1442
- /**
1443
- * Nuke the table
1444
- * @param {object} oSettings dataTables settings object
1445
- * @memberof DataTable#oApi
1446
- */
1447
- function _fnClearTable( settings )
1448
- {
1449
- settings.aoData.length = 0;
1450
- settings.aiDisplayMaster.length = 0;
1451
- settings.aiDisplay.length = 0;
1452
- }
1453
-
1454
-
1455
- /**
1456
- * Take an array of integers (index array) and remove a target integer (value - not
1457
- * the key!)
1458
- * @param {array} a Index array to target
1459
- * @param {int} iTarget value to find
1460
- * @memberof DataTable#oApi
1461
- */
1462
- function _fnDeleteIndex( a, iTarget, splice )
1463
- {
1464
- var iTargetIndex = -1;
1465
-
1466
- for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1467
- {
1468
- if ( a[i] == iTarget )
1469
- {
1470
- iTargetIndex = i;
1471
- }
1472
- else if ( a[i] > iTarget )
1473
- {
1474
- a[i]--;
1475
- }
1476
- }
1477
-
1478
- if ( iTargetIndex != -1 && splice === undefined )
1479
- {
1480
- a.splice( iTargetIndex, 1 );
1481
- }
1482
- }
1483
-
1484
-
1485
- /**
1486
- * Mark cached data as invalid such that a re-read of the data will occur when
1487
- * the cached data is next requested. Also update from the data source object.
1488
- *
1489
- * @param {object} settings DataTables settings object
1490
- * @param {int} rowIdx Row index to invalidate
1491
- * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
1492
- * or 'data'
1493
- * @param {int} [colIdx] Column index to invalidate. If undefined the whole
1494
- * row will be invalidated
1495
- * @memberof DataTable#oApi
1496
- *
1497
- * @todo For the modularisation of v1.11 this will need to become a callback, so
1498
- * the sort and filter methods can subscribe to it. That will required
1499
- * initialisation options for sorting, which is why it is not already baked in
1500
- */
1501
- function _fnInvalidate( settings, rowIdx, src, colIdx )
1502
- {
1503
- var row = settings.aoData[ rowIdx ];
1504
- var i, ien;
1505
- var cellWrite = function ( cell, col ) {
1506
- // This is very frustrating, but in IE if you just write directly
1507
- // to innerHTML, and elements that are overwritten are GC'ed,
1508
- // even if there is a reference to them elsewhere
1509
- while ( cell.childNodes.length ) {
1510
- cell.removeChild( cell.firstChild );
1511
- }
1512
-
1513
- cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
1514
- };
1515
-
1516
- // Are we reading last data from DOM or the data object?
1517
- if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
1518
- // Read the data from the DOM
1519
- row._aData = _fnGetRowElements(
1520
- settings, row, colIdx, colIdx === undefined ? undefined : row._aData
1521
- )
1522
- .data;
1523
- }
1524
- else {
1525
- // Reading from data object, update the DOM
1526
- var cells = row.anCells;
1527
-
1528
- if ( cells ) {
1529
- if ( colIdx !== undefined ) {
1530
- cellWrite( cells[colIdx], colIdx );
1531
- }
1532
- else {
1533
- for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1534
- cellWrite( cells[i], i );
1535
- }
1536
- }
1537
- }
1538
- }
1539
-
1540
- // For both row and cell invalidation, the cached data for sorting and
1541
- // filtering is nulled out
1542
- row._aSortData = null;
1543
- row._aFilterData = null;
1544
-
1545
- // Invalidate the type for a specific column (if given) or all columns since
1546
- // the data might have changed
1547
- var cols = settings.aoColumns;
1548
- if ( colIdx !== undefined ) {
1549
- cols[ colIdx ].sType = null;
1550
- }
1551
- else {
1552
- for ( i=0, ien=cols.length ; i<ien ; i++ ) {
1553
- cols[i].sType = null;
1554
- }
1555
-
1556
- // Update DataTables special `DT_*` attributes for the row
1557
- _fnRowAttributes( settings, row );
1558
- }
1559
- }
1560
-
1561
-
1562
- /**
1563
- * Build a data source object from an HTML row, reading the contents of the
1564
- * cells that are in the row.
1565
- *
1566
- * @param {object} settings DataTables settings object
1567
- * @param {node|object} TR element from which to read data or existing row
1568
- * object from which to re-read the data from the cells
1569
- * @param {int} [colIdx] Optional column index
1570
- * @param {array|object} [d] Data source object. If `colIdx` is given then this
1571
- * parameter should also be given and will be used to write the data into.
1572
- * Only the column in question will be written
1573
- * @returns {object} Object with two parameters: `data` the data read, in
1574
- * document order, and `cells` and array of nodes (they can be useful to the
1575
- * caller, so rather than needing a second traversal to get them, just return
1576
- * them from here).
1577
- * @memberof DataTable#oApi
1578
- */
1579
- function _fnGetRowElements( settings, row, colIdx, d )
1580
- {
1581
- var
1582
- tds = [],
1583
- td = row.firstChild,
1584
- name, col, o, i=0, contents,
1585
- columns = settings.aoColumns,
1586
- objectRead = settings._rowReadObject;
1587
-
1588
- // Allow the data object to be passed in, or construct
1589
- d = d || objectRead ? {} : [];
1590
-
1591
- var attr = function ( str, td ) {
1592
- if ( typeof str === 'string' ) {
1593
- var idx = str.indexOf('@');
1594
-
1595
- if ( idx !== -1 ) {
1596
- var attr = str.substring( idx+1 );
1597
- var setter = _fnSetObjectDataFn( str );
1598
- setter( d, td.getAttribute( attr ) );
1599
- }
1600
- }
1601
- };
1602
-
1603
- // Read data from a cell and store into the data object
1604
- var cellProcess = function ( cell ) {
1605
- if ( colIdx === undefined || colIdx === i ) {
1606
- col = columns[i];
1607
- contents = $.trim(cell.innerHTML);
1608
-
1609
- if ( col && col._bAttrSrc ) {
1610
- var setter = _fnSetObjectDataFn( col.mData._ );
1611
- setter( d, contents );
1612
-
1613
- attr( col.mData.sort, cell );
1614
- attr( col.mData.type, cell );
1615
- attr( col.mData.filter, cell );
1616
- }
1617
- else {
1618
- // Depending on the `data` option for the columns the data can
1619
- // be read to either an object or an array.
1620
- if ( objectRead ) {
1621
- if ( ! col._setter ) {
1622
- // Cache the setter function
1623
- col._setter = _fnSetObjectDataFn( col.mData );
1624
- }
1625
- col._setter( d, contents );
1626
- }
1627
- else {
1628
- d[i] = contents;
1629
- }
1630
- }
1631
- }
1632
-
1633
- i++;
1634
- };
1635
-
1636
- if ( td ) {
1637
- // `tr` element was passed in
1638
- while ( td ) {
1639
- name = td.nodeName.toUpperCase();
1640
-
1641
- if ( name == "TD" || name == "TH" ) {
1642
- cellProcess( td );
1643
- tds.push( td );
1644
- }
1645
-
1646
- td = td.nextSibling;
1647
- }
1648
- }
1649
- else {
1650
- // Existing row object passed in
1651
- tds = row.anCells;
1652
-
1653
- for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
1654
- cellProcess( tds[j] );
1655
- }
1656
- }
1657
-
1658
- // Read the ID from the DOM if present
1659
- var id = row.getAttribute( 'id' );
1660
- if ( id ) {
1661
- _fnSetObjectDataFn( settings.rowId )( d, id );
1662
- }
1663
-
1664
- return {
1665
- data: d,
1666
- cells: tds
1667
- };
1668
- }
1669
- /**
1670
- * Create a new TR element (and it's TD children) for a row
1671
- * @param {object} oSettings dataTables settings object
1672
- * @param {int} iRow Row to consider
1673
- * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
1674
- * DataTables will create a row automatically
1675
- * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1676
- * if nTr is.
1677
- * @memberof DataTable#oApi
1678
- */
1679
- function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
1680
- {
1681
- var
1682
- row = oSettings.aoData[iRow],
1683
- rowData = row._aData,
1684
- cells = [],
1685
- nTr, nTd, oCol,
1686
- i, iLen;
1687
-
1688
- if ( row.nTr === null )
1689
- {
1690
- nTr = nTrIn || document.createElement('tr');
1691
-
1692
- row.nTr = nTr;
1693
- row.anCells = cells;
1694
-
1695
- /* Use a private property on the node to allow reserve mapping from the node
1696
- * to the aoData array for fast look up
1697
- */
1698
- nTr._DT_RowIndex = iRow;
1699
-
1700
- /* Special parameters can be given by the data source to be used on the row */
1701
- _fnRowAttributes( oSettings, row );
1702
-
1703
- /* Process each column */
1704
- for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1705
- {
1706
- oCol = oSettings.aoColumns[i];
1707
-
1708
- nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
1709
- cells.push( nTd );
1710
-
1711
- // Need to create the HTML if new, or if a rendering function is defined
1712
- if ( !nTrIn || oCol.mRender || oCol.mData !== i )
1713
- {
1714
- nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
1715
- }
1716
-
1717
- /* Add user defined class */
1718
- if ( oCol.sClass )
1719
- {
1720
- nTd.className += ' '+oCol.sClass;
1721
- }
1722
-
1723
- // Visibility - add or remove as required
1724
- if ( oCol.bVisible && ! nTrIn )
1725
- {
1726
- nTr.appendChild( nTd );
1727
- }
1728
- else if ( ! oCol.bVisible && nTrIn )
1729
- {
1730
- nTd.parentNode.removeChild( nTd );
1731
- }
1732
-
1733
- if ( oCol.fnCreatedCell )
1734
- {
1735
- oCol.fnCreatedCell.call( oSettings.oInstance,
1736
- nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
1737
- );
1738
- }
1739
- }
1740
-
1741
- _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
1742
- }
1743
-
1744
- // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
1745
- // and deployed
1746
- row.nTr.setAttribute( 'role', 'row' );
1747
- }
1748
-
1749
-
1750
- /**
1751
- * Add attributes to a row based on the special `DT_*` parameters in a data
1752
- * source object.
1753
- * @param {object} settings DataTables settings object
1754
- * @param {object} DataTables row object for the row to be modified
1755
- * @memberof DataTable#oApi
1756
- */
1757
- function _fnRowAttributes( settings, row )
1758
- {
1759
- var tr = row.nTr;
1760
- var data = row._aData;
1761
-
1762
- if ( tr ) {
1763
- var id = settings.rowIdFn( data );
1764
-
1765
- if ( id ) {
1766
- tr.id = id;
1767
- }
1768
-
1769
- if ( data.DT_RowClass ) {
1770
- // Remove any classes added by DT_RowClass before
1771
- var a = data.DT_RowClass.split(' ');
1772
- row.__rowc = row.__rowc ?
1773
- _unique( row.__rowc.concat( a ) ) :
1774
- a;
1775
-
1776
- $(tr)
1777
- .removeClass( row.__rowc.join(' ') )
1778
- .addClass( data.DT_RowClass );
1779
- }
1780
-
1781
- if ( data.DT_RowAttr ) {
1782
- $(tr).attr( data.DT_RowAttr );
1783
- }
1784
-
1785
- if ( data.DT_RowData ) {
1786
- $(tr).data( data.DT_RowData );
1787
- }
1788
- }
1789
- }
1790
-
1791
-
1792
- /**
1793
- * Create the HTML header for the table
1794
- * @param {object} oSettings dataTables settings object
1795
- * @memberof DataTable#oApi
1796
- */
1797
- function _fnBuildHead( oSettings )
1798
- {
1799
- var i, ien, cell, row, column;
1800
- var thead = oSettings.nTHead;
1801
- var tfoot = oSettings.nTFoot;
1802
- var createHeader = $('th, td', thead).length === 0;
1803
- var classes = oSettings.oClasses;
1804
- var columns = oSettings.aoColumns;
1805
-
1806
- if ( createHeader ) {
1807
- row = $('<tr/>').appendTo( thead );
1808
- }
1809
-
1810
- for ( i=0, ien=columns.length ; i<ien ; i++ ) {
1811
- column = columns[i];
1812
- cell = $( column.nTh ).addClass( column.sClass );
1813
-
1814
- if ( createHeader ) {
1815
- cell.appendTo( row );
1816
- }
1817
-
1818
- // 1.11 move into sorting
1819
- if ( oSettings.oFeatures.bSort ) {
1820
- cell.addClass( column.sSortingClass );
1821
-
1822
- if ( column.bSortable !== false ) {
1823
- cell
1824
- .attr( 'tabindex', oSettings.iTabIndex )
1825
- .attr( 'aria-controls', oSettings.sTableId );
1826
-
1827
- _fnSortAttachListener( oSettings, column.nTh, i );
1828
- }
1829
- }
1830
-
1831
- if ( column.sTitle != cell[0].innerHTML ) {
1832
- cell.html( column.sTitle );
1833
- }
1834
-
1835
- _fnRenderer( oSettings, 'header' )(
1836
- oSettings, cell, column, classes
1837
- );
1838
- }
1839
-
1840
- if ( createHeader ) {
1841
- _fnDetectHeader( oSettings.aoHeader, thead );
1842
- }
1843
-
1844
- /* ARIA role for the rows */
1845
- $(thead).find('>tr').attr('role', 'row');
1846
-
1847
- /* Deal with the footer - add classes if required */
1848
- $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
1849
- $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
1850
-
1851
- // Cache the footer cells. Note that we only take the cells from the first
1852
- // row in the footer. If there is more than one row the user wants to
1853
- // interact with, they need to use the table().foot() method. Note also this
1854
- // allows cells to be used for multiple columns using colspan
1855
- if ( tfoot !== null ) {
1856
- var cells = oSettings.aoFooter[0];
1857
-
1858
- for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1859
- column = columns[i];
1860
- column.nTf = cells[i].cell;
1861
-
1862
- if ( column.sClass ) {
1863
- $(column.nTf).addClass( column.sClass );
1864
- }
1865
- }
1866
- }
1867
- }
1868
-
1869
-
1870
- /**
1871
- * Draw the header (or footer) element based on the column visibility states. The
1872
- * methodology here is to use the layout array from _fnDetectHeader, modified for
1873
- * the instantaneous column visibility, to construct the new layout. The grid is
1874
- * traversed over cell at a time in a rows x columns grid fashion, although each
1875
- * cell insert can cover multiple elements in the grid - which is tracks using the
1876
- * aApplied array. Cell inserts in the grid will only occur where there isn't
1877
- * already a cell in that position.
1878
- * @param {object} oSettings dataTables settings object
1879
- * @param array {objects} aoSource Layout array from _fnDetectHeader
1880
- * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
1881
- * @memberof DataTable#oApi
1882
- */
1883
- function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
1884
- {
1885
- var i, iLen, j, jLen, k, kLen, n, nLocalTr;
1886
- var aoLocal = [];
1887
- var aApplied = [];
1888
- var iColumns = oSettings.aoColumns.length;
1889
- var iRowspan, iColspan;
1890
-
1891
- if ( ! aoSource )
1892
- {
1893
- return;
1894
- }
1895
-
1896
- if ( bIncludeHidden === undefined )
1897
- {
1898
- bIncludeHidden = false;
1899
- }
1900
-
1901
- /* Make a copy of the master layout array, but without the visible columns in it */
1902
- for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
1903
- {
1904
- aoLocal[i] = aoSource[i].slice();
1905
- aoLocal[i].nTr = aoSource[i].nTr;
1906
-
1907
- /* Remove any columns which are currently hidden */
1908
- for ( j=iColumns-1 ; j>=0 ; j-- )
1909
- {
1910
- if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
1911
- {
1912
- aoLocal[i].splice( j, 1 );
1913
- }
1914
- }
1915
-
1916
- /* Prep the applied array - it needs an element for each row */
1917
- aApplied.push( [] );
1918
- }
1919
-
1920
- for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
1921
- {
1922
- nLocalTr = aoLocal[i].nTr;
1923
-
1924
- /* All cells are going to be replaced, so empty out the row */
1925
- if ( nLocalTr )
1926
- {
1927
- while( (n = nLocalTr.firstChild) )
1928
- {
1929
- nLocalTr.removeChild( n );
1930
- }
1931
- }
1932
-
1933
- for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
1934
- {
1935
- iRowspan = 1;
1936
- iColspan = 1;
1937
-
1938
- /* Check to see if there is already a cell (row/colspan) covering our target
1939
- * insert point. If there is, then there is nothing to do.
1940
- */
1941
- if ( aApplied[i][j] === undefined )
1942
- {
1943
- nLocalTr.appendChild( aoLocal[i][j].cell );
1944
- aApplied[i][j] = 1;
1945
-
1946
- /* Expand the cell to cover as many rows as needed */
1947
- while ( aoLocal[i+iRowspan] !== undefined &&
1948
- aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
1949
- {
1950
- aApplied[i+iRowspan][j] = 1;
1951
- iRowspan++;
1952
- }
1953
-
1954
- /* Expand the cell to cover as many columns as needed */
1955
- while ( aoLocal[i][j+iColspan] !== undefined &&
1956
- aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
1957
- {
1958
- /* Must update the applied array over the rows for the columns */
1959
- for ( k=0 ; k<iRowspan ; k++ )
1960
- {
1961
- aApplied[i+k][j+iColspan] = 1;
1962
- }
1963
- iColspan++;
1964
- }
1965
-
1966
- /* Do the actual expansion in the DOM */
1967
- $(aoLocal[i][j].cell)
1968
- .attr('rowspan', iRowspan)
1969
- .attr('colspan', iColspan);
1970
- }
1971
- }
1972
- }
1973
- }
1974
-
1975
-
1976
- /**
1977
- * Insert the required TR nodes into the table for display
1978
- * @param {object} oSettings dataTables settings object
1979
- * @memberof DataTable#oApi
1980
- */
1981
- function _fnDraw( oSettings )
1982
- {
1983
- /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
1984
- var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
1985
- if ( $.inArray( false, aPreDraw ) !== -1 )
1986
- {
1987
- _fnProcessingDisplay( oSettings, false );
1988
- return;
1989
- }
1990
-
1991
- var i, iLen, n;
1992
- var anRows = [];
1993
- var iRowCount = 0;
1994
- var asStripeClasses = oSettings.asStripeClasses;
1995
- var iStripes = asStripeClasses.length;
1996
- var iOpenRows = oSettings.aoOpenRows.length;
1997
- var oLang = oSettings.oLanguage;
1998
- var iInitDisplayStart = oSettings.iInitDisplayStart;
1999
- var bServerSide = _fnDataSource( oSettings ) == 'ssp';
2000
- var aiDisplay = oSettings.aiDisplay;
2001
-
2002
- oSettings.bDrawing = true;
2003
-
2004
- /* Check and see if we have an initial draw position from state saving */
2005
- if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
2006
- {
2007
- oSettings._iDisplayStart = bServerSide ?
2008
- iInitDisplayStart :
2009
- iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
2010
- 0 :
2011
- iInitDisplayStart;
2012
-
2013
- oSettings.iInitDisplayStart = -1;
2014
- }
2015
-
2016
- var iDisplayStart = oSettings._iDisplayStart;
2017
- var iDisplayEnd = oSettings.fnDisplayEnd();
2018
-
2019
- /* Server-side processing draw intercept */
2020
- if ( oSettings.bDeferLoading )
2021
- {
2022
- oSettings.bDeferLoading = false;
2023
- oSettings.iDraw++;
2024
- _fnProcessingDisplay( oSettings, false );
2025
- }
2026
- else if ( !bServerSide )
2027
- {
2028
- oSettings.iDraw++;
2029
- }
2030
- else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
2031
- {
2032
- return;
2033
- }
2034
-
2035
- if ( aiDisplay.length !== 0 )
2036
- {
2037
- var iStart = bServerSide ? 0 : iDisplayStart;
2038
- var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
2039
-
2040
- for ( var j=iStart ; j<iEnd ; j++ )
2041
- {
2042
- var iDataIndex = aiDisplay[j];
2043
- var aoData = oSettings.aoData[ iDataIndex ];
2044
- if ( aoData.nTr === null )
2045
- {
2046
- _fnCreateTr( oSettings, iDataIndex );
2047
- }
2048
-
2049
- var nRow = aoData.nTr;
2050
-
2051
- /* Remove the old striping classes and then add the new one */
2052
- if ( iStripes !== 0 )
2053
- {
2054
- var sStripe = asStripeClasses[ iRowCount % iStripes ];
2055
- if ( aoData._sRowStripe != sStripe )
2056
- {
2057
- $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
2058
- aoData._sRowStripe = sStripe;
2059
- }
2060
- }
2061
-
2062
- // Row callback functions - might want to manipulate the row
2063
- // iRowCount and j are not currently documented. Are they at all
2064
- // useful?
2065
- _fnCallbackFire( oSettings, 'aoRowCallback', null,
2066
- [nRow, aoData._aData, iRowCount, j] );
2067
-
2068
- anRows.push( nRow );
2069
- iRowCount++;
2070
- }
2071
- }
2072
- else
2073
- {
2074
- /* Table is empty - create a row with an empty message in it */
2075
- var sZero = oLang.sZeroRecords;
2076
- if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
2077
- {
2078
- sZero = oLang.sLoadingRecords;
2079
- }
2080
- else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
2081
- {
2082
- sZero = oLang.sEmptyTable;
2083
- }
2084
-
2085
- anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
2086
- .append( $('<td />', {
2087
- 'valign': 'top',
2088
- 'colSpan': _fnVisbleColumns( oSettings ),
2089
- 'class': oSettings.oClasses.sRowEmpty
2090
- } ).html( sZero ) )[0];
2091
- }
2092
-
2093
- /* Header and footer callbacks */
2094
- _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
2095
- _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2096
-
2097
- _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
2098
- _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2099
-
2100
- var body = $(oSettings.nTBody);
2101
-
2102
- body.children().detach();
2103
- body.append( $(anRows) );
2104
-
2105
- /* Call all required callback functions for the end of a draw */
2106
- _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
2107
-
2108
- /* Draw is complete, sorting and filtering must be as well */
2109
- oSettings.bSorted = false;
2110
- oSettings.bFiltered = false;
2111
- oSettings.bDrawing = false;
2112
- }
2113
-
2114
-
2115
- /**
2116
- * Redraw the table - taking account of the various features which are enabled
2117
- * @param {object} oSettings dataTables settings object
2118
- * @param {boolean} [holdPosition] Keep the current paging position. By default
2119
- * the paging is reset to the first page
2120
- * @memberof DataTable#oApi
2121
- */
2122
- function _fnReDraw( settings, holdPosition )
2123
- {
2124
- var
2125
- features = settings.oFeatures,
2126
- sort = features.bSort,
2127
- filter = features.bFilter;
2128
-
2129
- if ( sort ) {
2130
- _fnSort( settings );
2131
- }
2132
-
2133
- if ( filter ) {
2134
- _fnFilterComplete( settings, settings.oPreviousSearch );
2135
- }
2136
- else {
2137
- // No filtering, so we want to just use the display master
2138
- settings.aiDisplay = settings.aiDisplayMaster.slice();
2139
- }
2140
-
2141
- if ( holdPosition !== true ) {
2142
- settings._iDisplayStart = 0;
2143
- }
2144
-
2145
- // Let any modules know about the draw hold position state (used by
2146
- // scrolling internally)
2147
- settings._drawHold = holdPosition;
2148
-
2149
- _fnDraw( settings );
2150
-
2151
- settings._drawHold = false;
2152
- }
2153
-
2154
-
2155
- /**
2156
- * Add the options to the page HTML for the table
2157
- * @param {object} oSettings dataTables settings object
2158
- * @memberof DataTable#oApi
2159
- */
2160
- function _fnAddOptionsHtml ( oSettings )
2161
- {
2162
- var classes = oSettings.oClasses;
2163
- var table = $(oSettings.nTable);
2164
- var holding = $('<div/>').insertBefore( table ); // Holding element for speed
2165
- var features = oSettings.oFeatures;
2166
-
2167
- // All DataTables are wrapped in a div
2168
- var insert = $('<div/>', {
2169
- id: oSettings.sTableId+'_wrapper',
2170
- 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
2171
- } );
2172
-
2173
- oSettings.nHolding = holding[0];
2174
- oSettings.nTableWrapper = insert[0];
2175
- oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
2176
-
2177
- /* Loop over the user set positioning and place the elements as needed */
2178
- var aDom = oSettings.sDom.split('');
2179
- var featureNode, cOption, nNewNode, cNext, sAttr, j;
2180
- for ( var i=0 ; i<aDom.length ; i++ )
2181
- {
2182
- featureNode = null;
2183
- cOption = aDom[i];
2184
-
2185
- if ( cOption == '<' )
2186
- {
2187
- /* New container div */
2188
- nNewNode = $('<div/>')[0];
2189
-
2190
- /* Check to see if we should append an id and/or a class name to the container */
2191
- cNext = aDom[i+1];
2192
- if ( cNext == "'" || cNext == '"' )
2193
- {
2194
- sAttr = "";
2195
- j = 2;
2196
- while ( aDom[i+j] != cNext )
2197
- {
2198
- sAttr += aDom[i+j];
2199
- j++;
2200
- }
2201
-
2202
- /* Replace jQuery UI constants @todo depreciated */
2203
- if ( sAttr == "H" )
2204
- {
2205
- sAttr = classes.sJUIHeader;
2206
- }
2207
- else if ( sAttr == "F" )
2208
- {
2209
- sAttr = classes.sJUIFooter;
2210
- }
2211
-
2212
- /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
2213
- * breaks the string into parts and applies them as needed
2214
- */
2215
- if ( sAttr.indexOf('.') != -1 )
2216
- {
2217
- var aSplit = sAttr.split('.');
2218
- nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
2219
- nNewNode.className = aSplit[1];
2220
- }
2221
- else if ( sAttr.charAt(0) == "#" )
2222
- {
2223
- nNewNode.id = sAttr.substr(1, sAttr.length-1);
2224
- }
2225
- else
2226
- {
2227
- nNewNode.className = sAttr;
2228
- }
2229
-
2230
- i += j; /* Move along the position array */
2231
- }
2232
-
2233
- insert.append( nNewNode );
2234
- insert = $(nNewNode);
2235
- }
2236
- else if ( cOption == '>' )
2237
- {
2238
- /* End container div */
2239
- insert = insert.parent();
2240
- }
2241
- // @todo Move options into their own plugins?
2242
- else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
2243
- {
2244
- /* Length */
2245
- featureNode = _fnFeatureHtmlLength( oSettings );
2246
- }
2247
- else if ( cOption == 'f' && features.bFilter )
2248
- {
2249
- /* Filter */
2250
- featureNode = _fnFeatureHtmlFilter( oSettings );
2251
- }
2252
- else if ( cOption == 'r' && features.bProcessing )
2253
- {
2254
- /* pRocessing */
2255
- featureNode = _fnFeatureHtmlProcessing( oSettings );
2256
- }
2257
- else if ( cOption == 't' )
2258
- {
2259
- /* Table */
2260
- featureNode = _fnFeatureHtmlTable( oSettings );
2261
- }
2262
- else if ( cOption == 'i' && features.bInfo )
2263
- {
2264
- /* Info */
2265
- featureNode = _fnFeatureHtmlInfo( oSettings );
2266
- }
2267
- else if ( cOption == 'p' && features.bPaginate )
2268
- {
2269
- /* Pagination */
2270
- featureNode = _fnFeatureHtmlPaginate( oSettings );
2271
- }
2272
- else if ( DataTable.ext.feature.length !== 0 )
2273
- {
2274
- /* Plug-in features */
2275
- var aoFeatures = DataTable.ext.feature;
2276
- for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
2277
- {
2278
- if ( cOption == aoFeatures[k].cFeature )
2279
- {
2280
- featureNode = aoFeatures[k].fnInit( oSettings );
2281
- break;
2282
- }
2283
- }
2284
- }
2285
-
2286
- /* Add to the 2D features array */
2287
- if ( featureNode )
2288
- {
2289
- var aanFeatures = oSettings.aanFeatures;
2290
-
2291
- if ( ! aanFeatures[cOption] )
2292
- {
2293
- aanFeatures[cOption] = [];
2294
- }
2295
-
2296
- aanFeatures[cOption].push( featureNode );
2297
- insert.append( featureNode );
2298
- }
2299
- }
2300
-
2301
- /* Built our DOM structure - replace the holding div with what we want */
2302
- holding.replaceWith( insert );
2303
- oSettings.nHolding = null;
2304
- }
2305
-
2306
-
2307
- /**
2308
- * Use the DOM source to create up an array of header cells. The idea here is to
2309
- * create a layout grid (array) of rows x columns, which contains a reference
2310
- * to the cell that that point in the grid (regardless of col/rowspan), such that
2311
- * any column / row could be removed and the new grid constructed
2312
- * @param array {object} aLayout Array to store the calculated layout in
2313
- * @param {node} nThead The header/footer element for the table
2314
- * @memberof DataTable#oApi
2315
- */
2316
- function _fnDetectHeader ( aLayout, nThead )
2317
- {
2318
- var nTrs = $(nThead).children('tr');
2319
- var nTr, nCell;
2320
- var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
2321
- var bUnique;
2322
- var fnShiftCol = function ( a, i, j ) {
2323
- var k = a[i];
2324
- while ( k[j] ) {
2325
- j++;
2326
- }
2327
- return j;
2328
- };
2329
-
2330
- aLayout.splice( 0, aLayout.length );
2331
-
2332
- /* We know how many rows there are in the layout - so prep it */
2333
- for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2334
- {
2335
- aLayout.push( [] );
2336
- }
2337
-
2338
- /* Calculate a layout array */
2339
- for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2340
- {
2341
- nTr = nTrs[i];
2342
- iColumn = 0;
2343
-
2344
- /* For every cell in the row... */
2345
- nCell = nTr.firstChild;
2346
- while ( nCell ) {
2347
- if ( nCell.nodeName.toUpperCase() == "TD" ||
2348
- nCell.nodeName.toUpperCase() == "TH" )
2349
- {
2350
- /* Get the col and rowspan attributes from the DOM and sanitise them */
2351
- iColspan = nCell.getAttribute('colspan') * 1;
2352
- iRowspan = nCell.getAttribute('rowspan') * 1;
2353
- iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
2354
- iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
2355
-
2356
- /* There might be colspan cells already in this row, so shift our target
2357
- * accordingly
2358
- */
2359
- iColShifted = fnShiftCol( aLayout, i, iColumn );
2360
-
2361
- /* Cache calculation for unique columns */
2362
- bUnique = iColspan === 1 ? true : false;
2363
-
2364
- /* If there is col / rowspan, copy the information into the layout grid */
2365
- for ( l=0 ; l<iColspan ; l++ )
2366
- {
2367
- for ( k=0 ; k<iRowspan ; k++ )
2368
- {
2369
- aLayout[i+k][iColShifted+l] = {
2370
- "cell": nCell,
2371
- "unique": bUnique
2372
- };
2373
- aLayout[i+k].nTr = nTr;
2374
- }
2375
- }
2376
- }
2377
- nCell = nCell.nextSibling;
2378
- }
2379
- }
2380
- }
2381
-
2382
-
2383
- /**
2384
- * Get an array of unique th elements, one for each column
2385
- * @param {object} oSettings dataTables settings object
2386
- * @param {node} nHeader automatically detect the layout from this node - optional
2387
- * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
2388
- * @returns array {node} aReturn list of unique th's
2389
- * @memberof DataTable#oApi
2390
- */
2391
- function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
2392
- {
2393
- var aReturn = [];
2394
- if ( !aLayout )
2395
- {
2396
- aLayout = oSettings.aoHeader;
2397
- if ( nHeader )
2398
- {
2399
- aLayout = [];
2400
- _fnDetectHeader( aLayout, nHeader );
2401
- }
2402
- }
2403
-
2404
- for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
2405
- {
2406
- for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
2407
- {
2408
- if ( aLayout[i][j].unique &&
2409
- (!aReturn[j] || !oSettings.bSortCellsTop) )
2410
- {
2411
- aReturn[j] = aLayout[i][j].cell;
2412
- }
2413
- }
2414
- }
2415
-
2416
- return aReturn;
2417
- }
2418
-
2419
- /**
2420
- * Create an Ajax call based on the table's settings, taking into account that
2421
- * parameters can have multiple forms, and backwards compatibility.
2422
- *
2423
- * @param {object} oSettings dataTables settings object
2424
- * @param {array} data Data to send to the server, required by
2425
- * DataTables - may be augmented by developer callbacks
2426
- * @param {function} fn Callback function to run when data is obtained
2427
- */
2428
- function _fnBuildAjax( oSettings, data, fn )
2429
- {
2430
- // Compatibility with 1.9-, allow fnServerData and event to manipulate
2431
- _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
2432
-
2433
- // Convert to object based for 1.10+ if using the old array scheme which can
2434
- // come from server-side processing or serverParams
2435
- if ( data && $.isArray(data) ) {
2436
- var tmp = {};
2437
- var rbracket = /(.*?)\[\]$/;
2438
-
2439
- $.each( data, function (key, val) {
2440
- var match = val.name.match(rbracket);
2441
-
2442
- if ( match ) {
2443
- // Support for arrays
2444
- var name = match[0];
2445
-
2446
- if ( ! tmp[ name ] ) {
2447
- tmp[ name ] = [];
2448
- }
2449
- tmp[ name ].push( val.value );
2450
- }
2451
- else {
2452
- tmp[val.name] = val.value;
2453
- }
2454
- } );
2455
- data = tmp;
2456
- }
2457
-
2458
- var ajaxData;
2459
- var ajax = oSettings.ajax;
2460
- var instance = oSettings.oInstance;
2461
- var callback = function ( json ) {
2462
- _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
2463
- fn( json );
2464
- };
2465
-
2466
- if ( $.isPlainObject( ajax ) && ajax.data )
2467
- {
2468
- ajaxData = ajax.data;
2469
-
2470
- var newData = $.isFunction( ajaxData ) ?
2471
- ajaxData( data, oSettings ) : // fn can manipulate data or return
2472
- ajaxData; // an object object or array to merge
2473
-
2474
- // If the function returned something, use that alone
2475
- data = $.isFunction( ajaxData ) && newData ?
2476
- newData :
2477
- $.extend( true, data, newData );
2478
-
2479
- // Remove the data property as we've resolved it already and don't want
2480
- // jQuery to do it again (it is restored at the end of the function)
2481
- delete ajax.data;
2482
- }
2483
-
2484
- var baseAjax = {
2485
- "data": data,
2486
- "success": function (json) {
2487
- var error = json.error || json.sError;
2488
- if ( error ) {
2489
- _fnLog( oSettings, 0, error );
2490
- }
2491
-
2492
- oSettings.json = json;
2493
- callback( json );
2494
- },
2495
- "dataType": "json",
2496
- "cache": false,
2497
- "type": oSettings.sServerMethod,
2498
- "error": function (xhr, error, thrown) {
2499
- var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
2500
-
2501
- if ( $.inArray( true, ret ) === -1 ) {
2502
- if ( error == "parsererror" ) {
2503
- _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
2504
- }
2505
- else if ( xhr.readyState === 4 ) {
2506
- _fnLog( oSettings, 0, 'Ajax error', 7 );
2507
- }
2508
- }
2509
-
2510
- _fnProcessingDisplay( oSettings, false );
2511
- }
2512
- };
2513
-
2514
- // Store the data submitted for the API
2515
- oSettings.oAjaxData = data;
2516
-
2517
- // Allow plug-ins and external processes to modify the data
2518
- _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
2519
-
2520
- if ( oSettings.fnServerData )
2521
- {
2522
- // DataTables 1.9- compatibility
2523
- oSettings.fnServerData.call( instance,
2524
- oSettings.sAjaxSource,
2525
- $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
2526
- return { name: key, value: val };
2527
- } ),
2528
- callback,
2529
- oSettings
2530
- );
2531
- }
2532
- else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
2533
- {
2534
- // DataTables 1.9- compatibility
2535
- oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
2536
- url: ajax || oSettings.sAjaxSource
2537
- } ) );
2538
- }
2539
- else if ( $.isFunction( ajax ) )
2540
- {
2541
- // Is a function - let the caller define what needs to be done
2542
- oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
2543
- }
2544
- else
2545
- {
2546
- // Object to extend the base settings
2547
- oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
2548
-
2549
- // Restore for next time around
2550
- ajax.data = ajaxData;
2551
- }
2552
- }
2553
-
2554
-
2555
- /**
2556
- * Update the table using an Ajax call
2557
- * @param {object} settings dataTables settings object
2558
- * @returns {boolean} Block the table drawing or not
2559
- * @memberof DataTable#oApi
2560
- */
2561
- function _fnAjaxUpdate( settings )
2562
- {
2563
- if ( settings.bAjaxDataGet ) {
2564
- settings.iDraw++;
2565
- _fnProcessingDisplay( settings, true );
2566
-
2567
- _fnBuildAjax(
2568
- settings,
2569
- _fnAjaxParameters( settings ),
2570
- function(json) {
2571
- _fnAjaxUpdateDraw( settings, json );
2572
- }
2573
- );
2574
-
2575
- return false;
2576
- }
2577
- return true;
2578
- }
2579
-
2580
-
2581
- /**
2582
- * Build up the parameters in an object needed for a server-side processing
2583
- * request. Note that this is basically done twice, is different ways - a modern
2584
- * method which is used by default in DataTables 1.10 which uses objects and
2585
- * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
2586
- * the sAjaxSource option is used in the initialisation, or the legacyAjax
2587
- * option is set.
2588
- * @param {object} oSettings dataTables settings object
2589
- * @returns {bool} block the table drawing or not
2590
- * @memberof DataTable#oApi
2591
- */
2592
- function _fnAjaxParameters( settings )
2593
- {
2594
- var
2595
- columns = settings.aoColumns,
2596
- columnCount = columns.length,
2597
- features = settings.oFeatures,
2598
- preSearch = settings.oPreviousSearch,
2599
- preColSearch = settings.aoPreSearchCols,
2600
- i, data = [], dataProp, column, columnSearch,
2601
- sort = _fnSortFlatten( settings ),
2602
- displayStart = settings._iDisplayStart,
2603
- displayLength = features.bPaginate !== false ?
2604
- settings._iDisplayLength :
2605
- -1;
2606
-
2607
- var param = function ( name, value ) {
2608
- data.push( { 'name': name, 'value': value } );
2609
- };
2610
-
2611
- // DataTables 1.9- compatible method
2612
- param( 'sEcho', settings.iDraw );
2613
- param( 'iColumns', columnCount );
2614
- param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
2615
- param( 'iDisplayStart', displayStart );
2616
- param( 'iDisplayLength', displayLength );
2617
-
2618
- // DataTables 1.10+ method
2619
- var d = {
2620
- draw: settings.iDraw,
2621
- columns: [],
2622
- order: [],
2623
- start: displayStart,
2624
- length: displayLength,
2625
- search: {
2626
- value: preSearch.sSearch,
2627
- regex: preSearch.bRegex
2628
- }
2629
- };
2630
-
2631
- for ( i=0 ; i<columnCount ; i++ ) {
2632
- column = columns[i];
2633
- columnSearch = preColSearch[i];
2634
- dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
2635
-
2636
- d.columns.push( {
2637
- data: dataProp,
2638
- name: column.sName,
2639
- searchable: column.bSearchable,
2640
- orderable: column.bSortable,
2641
- search: {
2642
- value: columnSearch.sSearch,
2643
- regex: columnSearch.bRegex
2644
- }
2645
- } );
2646
-
2647
- param( "mDataProp_"+i, dataProp );
2648
-
2649
- if ( features.bFilter ) {
2650
- param( 'sSearch_'+i, columnSearch.sSearch );
2651
- param( 'bRegex_'+i, columnSearch.bRegex );
2652
- param( 'bSearchable_'+i, column.bSearchable );
2653
- }
2654
-
2655
- if ( features.bSort ) {
2656
- param( 'bSortable_'+i, column.bSortable );
2657
- }
2658
- }
2659
-
2660
- if ( features.bFilter ) {
2661
- param( 'sSearch', preSearch.sSearch );
2662
- param( 'bRegex', preSearch.bRegex );
2663
- }
2664
-
2665
- if ( features.bSort ) {
2666
- $.each( sort, function ( i, val ) {
2667
- d.order.push( { column: val.col, dir: val.dir } );
2668
-
2669
- param( 'iSortCol_'+i, val.col );
2670
- param( 'sSortDir_'+i, val.dir );
2671
- } );
2672
-
2673
- param( 'iSortingCols', sort.length );
2674
- }
2675
-
2676
- // If the legacy.ajax parameter is null, then we automatically decide which
2677
- // form to use, based on sAjaxSource
2678
- var legacy = DataTable.ext.legacy.ajax;
2679
- if ( legacy === null ) {
2680
- return settings.sAjaxSource ? data : d;
2681
- }
2682
-
2683
- // Otherwise, if legacy has been specified then we use that to decide on the
2684
- // form
2685
- return legacy ? data : d;
2686
- }
2687
-
2688
-
2689
- /**
2690
- * Data the data from the server (nuking the old) and redraw the table
2691
- * @param {object} oSettings dataTables settings object
2692
- * @param {object} json json data return from the server.
2693
- * @param {string} json.sEcho Tracking flag for DataTables to match requests
2694
- * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
2695
- * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
2696
- * @param {array} json.aaData The data to display on this page
2697
- * @param {string} [json.sColumns] Column ordering (sName, comma separated)
2698
- * @memberof DataTable#oApi
2699
- */
2700
- function _fnAjaxUpdateDraw ( settings, json )
2701
- {
2702
- // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
2703
- // Support both
2704
- var compat = function ( old, modern ) {
2705
- return json[old] !== undefined ? json[old] : json[modern];
2706
- };
2707
-
2708
- var data = _fnAjaxDataSrc( settings, json );
2709
- var draw = compat( 'sEcho', 'draw' );
2710
- var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
2711
- var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
2712
-
2713
- if ( draw ) {
2714
- // Protect against out of sequence returns
2715
- if ( draw*1 < settings.iDraw ) {
2716
- return;
2717
- }
2718
- settings.iDraw = draw * 1;
2719
- }
2720
-
2721
- _fnClearTable( settings );
2722
- settings._iRecordsTotal = parseInt(recordsTotal, 10);
2723
- settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
2724
-
2725
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
2726
- _fnAddData( settings, data[i] );
2727
- }
2728
- settings.aiDisplay = settings.aiDisplayMaster.slice();
2729
-
2730
- settings.bAjaxDataGet = false;
2731
- _fnDraw( settings );
2732
-
2733
- if ( ! settings._bInitComplete ) {
2734
- _fnInitComplete( settings, json );
2735
- }
2736
-
2737
- settings.bAjaxDataGet = true;
2738
- _fnProcessingDisplay( settings, false );
2739
- }
2740
-
2741
-
2742
- /**
2743
- * Get the data from the JSON data source to use for drawing a table. Using
2744
- * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
2745
- * source object, or from a processing function.
2746
- * @param {object} oSettings dataTables settings object
2747
- * @param {object} json Data source object / array from the server
2748
- * @return {array} Array of data to use
2749
- */
2750
- function _fnAjaxDataSrc ( oSettings, json )
2751
- {
2752
- var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
2753
- oSettings.ajax.dataSrc :
2754
- oSettings.sAjaxDataProp; // Compatibility with 1.9-.
2755
-
2756
- // Compatibility with 1.9-. In order to read from aaData, check if the
2757
- // default has been changed, if not, check for aaData
2758
- if ( dataSrc === 'data' ) {
2759
- return json.aaData || json[dataSrc];
2760
- }
2761
-
2762
- return dataSrc !== "" ?
2763
- _fnGetObjectDataFn( dataSrc )( json ) :
2764
- json;
2765
- }
2766
-
2767
- /**
2768
- * Generate the node required for filtering text
2769
- * @returns {node} Filter control element
2770
- * @param {object} oSettings dataTables settings object
2771
- * @memberof DataTable#oApi
2772
- */
2773
- function _fnFeatureHtmlFilter ( settings )
2774
- {
2775
- var classes = settings.oClasses;
2776
- var tableId = settings.sTableId;
2777
- var language = settings.oLanguage;
2778
- var previousSearch = settings.oPreviousSearch;
2779
- var features = settings.aanFeatures;
2780
- var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
2781
-
2782
- var str = language.sSearch;
2783
- str = str.match(/_INPUT_/) ?
2784
- str.replace('_INPUT_', input) :
2785
- str+input;
2786
-
2787
- var filter = $('<div/>', {
2788
- 'id': ! features.f ? tableId+'_filter' : null,
2789
- 'class': classes.sFilter
2790
- } )
2791
- .append( $('<label/>' ).append( str ) );
2792
-
2793
- var searchFn = function() {
2794
- /* Update all other filter input elements for the new display */
2795
- var n = features.f;
2796
- var val = !this.value ? "" : this.value; // mental IE8 fix :-(
2797
-
2798
- /* Now do the filter */
2799
- if ( val != previousSearch.sSearch ) {
2800
- _fnFilterComplete( settings, {
2801
- "sSearch": val,
2802
- "bRegex": previousSearch.bRegex,
2803
- "bSmart": previousSearch.bSmart ,
2804
- "bCaseInsensitive": previousSearch.bCaseInsensitive
2805
- } );
2806
-
2807
- // Need to redraw, without resorting
2808
- settings._iDisplayStart = 0;
2809
- _fnDraw( settings );
2810
- }
2811
- };
2812
-
2813
- var searchDelay = settings.searchDelay !== null ?
2814
- settings.searchDelay :
2815
- _fnDataSource( settings ) === 'ssp' ?
2816
- 400 :
2817
- 0;
2818
-
2819
- var jqFilter = $('input', filter)
2820
- .val( previousSearch.sSearch )
2821
- .attr( 'placeholder', language.sSearchPlaceholder )
2822
- .bind(
2823
- 'keyup.DT search.DT input.DT paste.DT cut.DT',
2824
- searchDelay ?
2825
- _fnThrottle( searchFn, searchDelay ) :
2826
- searchFn
2827
- )
2828
- .bind( 'keypress.DT', function(e) {
2829
- /* Prevent form submission */
2830
- if ( e.keyCode == 13 ) {
2831
- return false;
2832
- }
2833
- } )
2834
- .attr('aria-controls', tableId);
2835
-
2836
- // Update the input elements whenever the table is filtered
2837
- $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
2838
- if ( settings === s ) {
2839
- // IE9 throws an 'unknown error' if document.activeElement is used
2840
- // inside an iframe or frame...
2841
- try {
2842
- if ( jqFilter[0] !== document.activeElement ) {
2843
- jqFilter.val( previousSearch.sSearch );
2844
- }
2845
- }
2846
- catch ( e ) {}
2847
- }
2848
- } );
2849
-
2850
- return filter[0];
2851
- }
2852
-
2853
-
2854
- /**
2855
- * Filter the table using both the global filter and column based filtering
2856
- * @param {object} oSettings dataTables settings object
2857
- * @param {object} oSearch search information
2858
- * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
2859
- * @memberof DataTable#oApi
2860
- */
2861
- function _fnFilterComplete ( oSettings, oInput, iForce )
2862
- {
2863
- var oPrevSearch = oSettings.oPreviousSearch;
2864
- var aoPrevSearch = oSettings.aoPreSearchCols;
2865
- var fnSaveFilter = function ( oFilter ) {
2866
- /* Save the filtering values */
2867
- oPrevSearch.sSearch = oFilter.sSearch;
2868
- oPrevSearch.bRegex = oFilter.bRegex;
2869
- oPrevSearch.bSmart = oFilter.bSmart;
2870
- oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
2871
- };
2872
- var fnRegex = function ( o ) {
2873
- // Backwards compatibility with the bEscapeRegex option
2874
- return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
2875
- };
2876
-
2877
- // Resolve any column types that are unknown due to addition or invalidation
2878
- // @todo As per sort - can this be moved into an event handler?
2879
- _fnColumnTypes( oSettings );
2880
-
2881
- /* In server-side processing all filtering is done by the server, so no point hanging around here */
2882
- if ( _fnDataSource( oSettings ) != 'ssp' )
2883
- {
2884
- /* Global filter */
2885
- _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
2886
- fnSaveFilter( oInput );
2887
-
2888
- /* Now do the individual column filter */
2889
- for ( var i=0 ; i<aoPrevSearch.length ; i++ )
2890
- {
2891
- _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
2892
- aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
2893
- }
2894
-
2895
- /* Custom filtering */
2896
- _fnFilterCustom( oSettings );
2897
- }
2898
- else
2899
- {
2900
- fnSaveFilter( oInput );
2901
- }
2902
-
2903
- /* Tell the draw function we have been filtering */
2904
- oSettings.bFiltered = true;
2905
- _fnCallbackFire( oSettings, null, 'search', [oSettings] );
2906
- }
2907
-
2908
-
2909
- /**
2910
- * Apply custom filtering functions
2911
- * @param {object} oSettings dataTables settings object
2912
- * @memberof DataTable#oApi
2913
- */
2914
- function _fnFilterCustom( settings )
2915
- {
2916
- var filters = DataTable.ext.search;
2917
- var displayRows = settings.aiDisplay;
2918
- var row, rowIdx;
2919
-
2920
- for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
2921
- var rows = [];
2922
-
2923
- // Loop over each row and see if it should be included
2924
- for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
2925
- rowIdx = displayRows[ j ];
2926
- row = settings.aoData[ rowIdx ];
2927
-
2928
- if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
2929
- rows.push( rowIdx );
2930
- }
2931
- }
2932
-
2933
- // So the array reference doesn't break set the results into the
2934
- // existing array
2935
- displayRows.length = 0;
2936
- displayRows.push.apply( displayRows, rows );
2937
- }
2938
- }
2939
-
2940
-
2941
- /**
2942
- * Filter the table on a per-column basis
2943
- * @param {object} oSettings dataTables settings object
2944
- * @param {string} sInput string to filter on
2945
- * @param {int} iColumn column to filter
2946
- * @param {bool} bRegex treat search string as a regular expression or not
2947
- * @param {bool} bSmart use smart filtering or not
2948
- * @param {bool} bCaseInsensitive Do case insenstive matching or not
2949
- * @memberof DataTable#oApi
2950
- */
2951
- function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
2952
- {
2953
- if ( searchStr === '' ) {
2954
- return;
2955
- }
2956
-
2957
- var data;
2958
- var display = settings.aiDisplay;
2959
- var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
2960
-
2961
- for ( var i=display.length-1 ; i>=0 ; i-- ) {
2962
- data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
2963
-
2964
- if ( ! rpSearch.test( data ) ) {
2965
- display.splice( i, 1 );
2966
- }
2967
- }
2968
- }
2969
-
2970
-
2971
- /**
2972
- * Filter the data table based on user input and draw the table
2973
- * @param {object} settings dataTables settings object
2974
- * @param {string} input string to filter on
2975
- * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
2976
- * @param {bool} regex treat as a regular expression or not
2977
- * @param {bool} smart perform smart filtering or not
2978
- * @param {bool} caseInsensitive Do case insenstive matching or not
2979
- * @memberof DataTable#oApi
2980
- */
2981
- function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
2982
- {
2983
- var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
2984
- var prevSearch = settings.oPreviousSearch.sSearch;
2985
- var displayMaster = settings.aiDisplayMaster;
2986
- var display, invalidated, i;
2987
-
2988
- // Need to take account of custom filtering functions - always filter
2989
- if ( DataTable.ext.search.length !== 0 ) {
2990
- force = true;
2991
- }
2992
-
2993
- // Check if any of the rows were invalidated
2994
- invalidated = _fnFilterData( settings );
2995
-
2996
- // If the input is blank - we just want the full data set
2997
- if ( input.length <= 0 ) {
2998
- settings.aiDisplay = displayMaster.slice();
2999
- }
3000
- else {
3001
- // New search - start from the master array
3002
- if ( invalidated ||
3003
- force ||
3004
- prevSearch.length > input.length ||
3005
- input.indexOf(prevSearch) !== 0 ||
3006
- settings.bSorted // On resort, the display master needs to be
3007
- // re-filtered since indexes will have changed
3008
- ) {
3009
- settings.aiDisplay = displayMaster.slice();
3010
- }
3011
-
3012
- // Search the display array
3013
- display = settings.aiDisplay;
3014
-
3015
- for ( i=display.length-1 ; i>=0 ; i-- ) {
3016
- if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
3017
- display.splice( i, 1 );
3018
- }
3019
- }
3020
- }
3021
- }
3022
-
3023
-
3024
- /**
3025
- * Build a regular expression object suitable for searching a table
3026
- * @param {string} sSearch string to search for
3027
- * @param {bool} bRegex treat as a regular expression or not
3028
- * @param {bool} bSmart perform smart filtering or not
3029
- * @param {bool} bCaseInsensitive Do case insensitive matching or not
3030
- * @returns {RegExp} constructed object
3031
- * @memberof DataTable#oApi
3032
- */
3033
- function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
3034
- {
3035
- search = regex ?
3036
- search :
3037
- _fnEscapeRegex( search );
3038
-
3039
- if ( smart ) {
3040
- /* For smart filtering we want to allow the search to work regardless of
3041
- * word order. We also want double quoted text to be preserved, so word
3042
- * order is important - a la google. So this is what we want to
3043
- * generate:
3044
- *
3045
- * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
3046
- */
3047
- var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
3048
- if ( word.charAt(0) === '"' ) {
3049
- var m = word.match( /^"(.*)"$/ );
3050
- word = m ? m[1] : word;
3051
- }
3052
-
3053
- return word.replace('"', '');
3054
- } );
3055
-
3056
- search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
3057
- }
3058
-
3059
- return new RegExp( search, caseInsensitive ? 'i' : '' );
3060
- }
3061
-
3062
-
3063
- /**
3064
- * Escape a string such that it can be used in a regular expression
3065
- * @param {string} sVal string to escape
3066
- * @returns {string} escaped string
3067
- * @memberof DataTable#oApi
3068
- */
3069
- function _fnEscapeRegex ( sVal )
3070
- {
3071
- return sVal.replace( _re_escape_regex, '\\$1' );
3072
- }
3073
-
3074
-
3075
-
3076
- var __filter_div = $('<div>')[0];
3077
- var __filter_div_textContent = __filter_div.textContent !== undefined;
3078
-
3079
- // Update the filtering data for each row if needed (by invalidation or first run)
3080
- function _fnFilterData ( settings )
3081
- {
3082
- var columns = settings.aoColumns;
3083
- var column;
3084
- var i, j, ien, jen, filterData, cellData, row;
3085
- var fomatters = DataTable.ext.type.search;
3086
- var wasInvalidated = false;
3087
-
3088
- for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
3089
- row = settings.aoData[i];
3090
-
3091
- if ( ! row._aFilterData ) {
3092
- filterData = [];
3093
-
3094
- for ( j=0, jen=columns.length ; j<jen ; j++ ) {
3095
- column = columns[j];
3096
-
3097
- if ( column.bSearchable ) {
3098
- cellData = _fnGetCellData( settings, i, j, 'filter' );
3099
-
3100
- if ( fomatters[ column.sType ] ) {
3101
- cellData = fomatters[ column.sType ]( cellData );
3102
- }
3103
-
3104
- // Search in DataTables 1.10 is string based. In 1.11 this
3105
- // should be altered to also allow strict type checking.
3106
- if ( cellData === null ) {
3107
- cellData = '';
3108
- }
3109
-
3110
- if ( typeof cellData !== 'string' && cellData.toString ) {
3111
- cellData = cellData.toString();
3112
- }
3113
- }
3114
- else {
3115
- cellData = '';
3116
- }
3117
-
3118
- // If it looks like there is an HTML entity in the string,
3119
- // attempt to decode it so sorting works as expected. Note that
3120
- // we could use a single line of jQuery to do this, but the DOM
3121
- // method used here is much faster http://jsperf.com/html-decode
3122
- if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
3123
- __filter_div.innerHTML = cellData;
3124
- cellData = __filter_div_textContent ?
3125
- __filter_div.textContent :
3126
- __filter_div.innerText;
3127
- }
3128
-
3129
- if ( cellData.replace ) {
3130
- cellData = cellData.replace(/[\r\n]/g, '');
3131
- }
3132
-
3133
- filterData.push( cellData );
3134
- }
3135
-
3136
- row._aFilterData = filterData;
3137
- row._sFilterRow = filterData.join(' ');
3138
- wasInvalidated = true;
3139
- }
3140
- }
3141
-
3142
- return wasInvalidated;
3143
- }
3144
-
3145
-
3146
- /**
3147
- * Convert from the internal Hungarian notation to camelCase for external
3148
- * interaction
3149
- * @param {object} obj Object to convert
3150
- * @returns {object} Inverted object
3151
- * @memberof DataTable#oApi
3152
- */
3153
- function _fnSearchToCamel ( obj )
3154
- {
3155
- return {
3156
- search: obj.sSearch,
3157
- smart: obj.bSmart,
3158
- regex: obj.bRegex,
3159
- caseInsensitive: obj.bCaseInsensitive
3160
- };
3161
- }
3162
-
3163
-
3164
-
3165
- /**
3166
- * Convert from camelCase notation to the internal Hungarian. We could use the
3167
- * Hungarian convert function here, but this is cleaner
3168
- * @param {object} obj Object to convert
3169
- * @returns {object} Inverted object
3170
- * @memberof DataTable#oApi
3171
- */
3172
- function _fnSearchToHung ( obj )
3173
- {
3174
- return {
3175
- sSearch: obj.search,
3176
- bSmart: obj.smart,
3177
- bRegex: obj.regex,
3178
- bCaseInsensitive: obj.caseInsensitive
3179
- };
3180
- }
3181
-
3182
- /**
3183
- * Generate the node required for the info display
3184
- * @param {object} oSettings dataTables settings object
3185
- * @returns {node} Information element
3186
- * @memberof DataTable#oApi
3187
- */
3188
- function _fnFeatureHtmlInfo ( settings )
3189
- {
3190
- var
3191
- tid = settings.sTableId,
3192
- nodes = settings.aanFeatures.i,
3193
- n = $('<div/>', {
3194
- 'class': settings.oClasses.sInfo,
3195
- 'id': ! nodes ? tid+'_info' : null
3196
- } );
3197
-
3198
- if ( ! nodes ) {
3199
- // Update display on each draw
3200
- settings.aoDrawCallback.push( {
3201
- "fn": _fnUpdateInfo,
3202
- "sName": "information"
3203
- } );
3204
-
3205
- n
3206
- .attr( 'role', 'status' )
3207
- .attr( 'aria-live', 'polite' );
3208
-
3209
- // Table is described by our info div
3210
- $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
3211
- }
3212
-
3213
- return n[0];
3214
- }
3215
-
3216
-
3217
- /**
3218
- * Update the information elements in the display
3219
- * @param {object} settings dataTables settings object
3220
- * @memberof DataTable#oApi
3221
- */
3222
- function _fnUpdateInfo ( settings )
3223
- {
3224
- /* Show information about the table */
3225
- var nodes = settings.aanFeatures.i;
3226
- if ( nodes.length === 0 ) {
3227
- return;
3228
- }
3229
-
3230
- var
3231
- lang = settings.oLanguage,
3232
- start = settings._iDisplayStart+1,
3233
- end = settings.fnDisplayEnd(),
3234
- max = settings.fnRecordsTotal(),
3235
- total = settings.fnRecordsDisplay(),
3236
- out = total ?
3237
- lang.sInfo :
3238
- lang.sInfoEmpty;
3239
-
3240
- if ( total !== max ) {
3241
- /* Record set after filtering */
3242
- out += ' ' + lang.sInfoFiltered;
3243
- }
3244
-
3245
- // Convert the macros
3246
- out += lang.sInfoPostFix;
3247
- out = _fnInfoMacros( settings, out );
3248
-
3249
- var callback = lang.fnInfoCallback;
3250
- if ( callback !== null ) {
3251
- out = callback.call( settings.oInstance,
3252
- settings, start, end, max, total, out
3253
- );
3254
- }
3255
-
3256
- $(nodes).html( out );
3257
- }
3258
-
3259
-
3260
- function _fnInfoMacros ( settings, str )
3261
- {
3262
- // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
3263
- // internally
3264
- var
3265
- formatter = settings.fnFormatNumber,
3266
- start = settings._iDisplayStart+1,
3267
- len = settings._iDisplayLength,
3268
- vis = settings.fnRecordsDisplay(),
3269
- all = len === -1;
3270
-
3271
- return str.
3272
- replace(/_START_/g, formatter.call( settings, start ) ).
3273
- replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
3274
- replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
3275
- replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
3276
- replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
3277
- replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
3278
- }
3279
-
3280
-
3281
-
3282
- /**
3283
- * Draw the table for the first time, adding all required features
3284
- * @param {object} settings dataTables settings object
3285
- * @memberof DataTable#oApi
3286
- */
3287
- function _fnInitialise ( settings )
3288
- {
3289
- var i, iLen, iAjaxStart=settings.iInitDisplayStart;
3290
- var columns = settings.aoColumns, column;
3291
- var features = settings.oFeatures;
3292
- var deferLoading = settings.bDeferLoading; // value modified by the draw
3293
-
3294
- /* Ensure that the table data is fully initialised */
3295
- if ( ! settings.bInitialised ) {
3296
- setTimeout( function(){ _fnInitialise( settings ); }, 200 );
3297
- return;
3298
- }
3299
-
3300
- /* Show the display HTML options */
3301
- _fnAddOptionsHtml( settings );
3302
-
3303
- /* Build and draw the header / footer for the table */
3304
- _fnBuildHead( settings );
3305
- _fnDrawHead( settings, settings.aoHeader );
3306
- _fnDrawHead( settings, settings.aoFooter );
3307
-
3308
- /* Okay to show that something is going on now */
3309
- _fnProcessingDisplay( settings, true );
3310
-
3311
- /* Calculate sizes for columns */
3312
- if ( features.bAutoWidth ) {
3313
- _fnCalculateColumnWidths( settings );
3314
- }
3315
-
3316
- for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
3317
- column = columns[i];
3318
-
3319
- if ( column.sWidth ) {
3320
- column.nTh.style.width = _fnStringToCss( column.sWidth );
3321
- }
3322
- }
3323
-
3324
- _fnCallbackFire( settings, null, 'preInit', [settings] );
3325
-
3326
- // If there is default sorting required - let's do it. The sort function
3327
- // will do the drawing for us. Otherwise we draw the table regardless of the
3328
- // Ajax source - this allows the table to look initialised for Ajax sourcing
3329
- // data (show 'loading' message possibly)
3330
- _fnReDraw( settings );
3331
-
3332
- // Server-side processing init complete is done by _fnAjaxUpdateDraw
3333
- var dataSrc = _fnDataSource( settings );
3334
- if ( dataSrc != 'ssp' || deferLoading ) {
3335
- // if there is an ajax source load the data
3336
- if ( dataSrc == 'ajax' ) {
3337
- _fnBuildAjax( settings, [], function(json) {
3338
- var aData = _fnAjaxDataSrc( settings, json );
3339
-
3340
- // Got the data - add it to the table
3341
- for ( i=0 ; i<aData.length ; i++ ) {
3342
- _fnAddData( settings, aData[i] );
3343
- }
3344
-
3345
- // Reset the init display for cookie saving. We've already done
3346
- // a filter, and therefore cleared it before. So we need to make
3347
- // it appear 'fresh'
3348
- settings.iInitDisplayStart = iAjaxStart;
3349
-
3350
- _fnReDraw( settings );
3351
-
3352
- _fnProcessingDisplay( settings, false );
3353
- _fnInitComplete( settings, json );
3354
- }, settings );
3355
- }
3356
- else {
3357
- _fnProcessingDisplay( settings, false );
3358
- _fnInitComplete( settings );
3359
- }
3360
- }
3361
- }
3362
-
3363
-
3364
- /**
3365
- * Draw the table for the first time, adding all required features
3366
- * @param {object} oSettings dataTables settings object
3367
- * @param {object} [json] JSON from the server that completed the table, if using Ajax source
3368
- * with client-side processing (optional)
3369
- * @memberof DataTable#oApi
3370
- */
3371
- function _fnInitComplete ( settings, json )
3372
- {
3373
- settings._bInitComplete = true;
3374
-
3375
- // When data was added after the initialisation (data or Ajax) we need to
3376
- // calculate the column sizing
3377
- if ( json || settings.oInit.aaData ) {
3378
- _fnAdjustColumnSizing( settings );
3379
- }
3380
-
3381
- _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
3382
- }
3383
-
3384
-
3385
- function _fnLengthChange ( settings, val )
3386
- {
3387
- var len = parseInt( val, 10 );
3388
- settings._iDisplayLength = len;
3389
-
3390
- _fnLengthOverflow( settings );
3391
-
3392
- // Fire length change event
3393
- _fnCallbackFire( settings, null, 'length', [settings, len] );
3394
- }
3395
-
3396
-
3397
- /**
3398
- * Generate the node required for user display length changing
3399
- * @param {object} settings dataTables settings object
3400
- * @returns {node} Display length feature node
3401
- * @memberof DataTable#oApi
3402
- */
3403
- function _fnFeatureHtmlLength ( settings )
3404
- {
3405
- var
3406
- classes = settings.oClasses,
3407
- tableId = settings.sTableId,
3408
- menu = settings.aLengthMenu,
3409
- d2 = $.isArray( menu[0] ),
3410
- lengths = d2 ? menu[0] : menu,
3411
- language = d2 ? menu[1] : menu;
3412
-
3413
- var select = $('<select/>', {
3414
- 'name': tableId+'_length',
3415
- 'aria-controls': tableId,
3416
- 'class': classes.sLengthSelect
3417
- } );
3418
-
3419
- for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
3420
- select[0][ i ] = new Option( language[i], lengths[i] );
3421
- }
3422
-
3423
- var div = $('<div><label/></div>').addClass( classes.sLength );
3424
- if ( ! settings.aanFeatures.l ) {
3425
- div[0].id = tableId+'_length';
3426
- }
3427
-
3428
- div.children().append(
3429
- settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
3430
- );
3431
-
3432
- // Can't use `select` variable as user might provide their own and the
3433
- // reference is broken by the use of outerHTML
3434
- $('select', div)
3435
- .val( settings._iDisplayLength )
3436
- .bind( 'change.DT', function(e) {
3437
- _fnLengthChange( settings, $(this).val() );
3438
- _fnDraw( settings );
3439
- } );
3440
-
3441
- // Update node value whenever anything changes the table's length
3442
- $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
3443
- if ( settings === s ) {
3444
- $('select', div).val( len );
3445
- }
3446
- } );
3447
-
3448
- return div[0];
3449
- }
3450
-
3451
-
3452
-
3453
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3454
- * Note that most of the paging logic is done in
3455
- * DataTable.ext.pager
3456
- */
3457
-
3458
- /**
3459
- * Generate the node required for default pagination
3460
- * @param {object} oSettings dataTables settings object
3461
- * @returns {node} Pagination feature node
3462
- * @memberof DataTable#oApi
3463
- */
3464
- function _fnFeatureHtmlPaginate ( settings )
3465
- {
3466
- var
3467
- type = settings.sPaginationType,
3468
- plugin = DataTable.ext.pager[ type ],
3469
- modern = typeof plugin === 'function',
3470
- redraw = function( settings ) {
3471
- _fnDraw( settings );
3472
- },
3473
- node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
3474
- features = settings.aanFeatures;
3475
-
3476
- if ( ! modern ) {
3477
- plugin.fnInit( settings, node, redraw );
3478
- }
3479
-
3480
- /* Add a draw callback for the pagination on first instance, to update the paging display */
3481
- if ( ! features.p )
3482
- {
3483
- node.id = settings.sTableId+'_paginate';
3484
-
3485
- settings.aoDrawCallback.push( {
3486
- "fn": function( settings ) {
3487
- if ( modern ) {
3488
- var
3489
- start = settings._iDisplayStart,
3490
- len = settings._iDisplayLength,
3491
- visRecords = settings.fnRecordsDisplay(),
3492
- all = len === -1,
3493
- page = all ? 0 : Math.ceil( start / len ),
3494
- pages = all ? 1 : Math.ceil( visRecords / len ),
3495
- buttons = plugin(page, pages),
3496
- i, ien;
3497
-
3498
- for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
3499
- _fnRenderer( settings, 'pageButton' )(
3500
- settings, features.p[i], i, buttons, page, pages
3501
- );
3502
- }
3503
- }
3504
- else {
3505
- plugin.fnUpdate( settings, redraw );
3506
- }
3507
- },
3508
- "sName": "pagination"
3509
- } );
3510
- }
3511
-
3512
- return node;
3513
- }
3514
-
3515
-
3516
- /**
3517
- * Alter the display settings to change the page
3518
- * @param {object} settings DataTables settings object
3519
- * @param {string|int} action Paging action to take: "first", "previous",
3520
- * "next" or "last" or page number to jump to (integer)
3521
- * @param [bool] redraw Automatically draw the update or not
3522
- * @returns {bool} true page has changed, false - no change
3523
- * @memberof DataTable#oApi
3524
- */
3525
- function _fnPageChange ( settings, action, redraw )
3526
- {
3527
- var
3528
- start = settings._iDisplayStart,
3529
- len = settings._iDisplayLength,
3530
- records = settings.fnRecordsDisplay();
3531
-
3532
- if ( records === 0 || len === -1 )
3533
- {
3534
- start = 0;
3535
- }
3536
- else if ( typeof action === "number" )
3537
- {
3538
- start = action * len;
3539
-
3540
- if ( start > records )
3541
- {
3542
- start = 0;
3543
- }
3544
- }
3545
- else if ( action == "first" )
3546
- {
3547
- start = 0;
3548
- }
3549
- else if ( action == "previous" )
3550
- {
3551
- start = len >= 0 ?
3552
- start - len :
3553
- 0;
3554
-
3555
- if ( start < 0 )
3556
- {
3557
- start = 0;
3558
- }
3559
- }
3560
- else if ( action == "next" )
3561
- {
3562
- if ( start + len < records )
3563
- {
3564
- start += len;
3565
- }
3566
- }
3567
- else if ( action == "last" )
3568
- {
3569
- start = Math.floor( (records-1) / len) * len;
3570
- }
3571
- else
3572
- {
3573
- _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
3574
- }
3575
-
3576
- var changed = settings._iDisplayStart !== start;
3577
- settings._iDisplayStart = start;
3578
-
3579
- if ( changed ) {
3580
- _fnCallbackFire( settings, null, 'page', [settings] );
3581
-
3582
- if ( redraw ) {
3583
- _fnDraw( settings );
3584
- }
3585
- }
3586
-
3587
- return changed;
3588
- }
3589
-
3590
-
3591
-
3592
- /**
3593
- * Generate the node required for the processing node
3594
- * @param {object} settings dataTables settings object
3595
- * @returns {node} Processing element
3596
- * @memberof DataTable#oApi
3597
- */
3598
- function _fnFeatureHtmlProcessing ( settings )
3599
- {
3600
- return $('<div/>', {
3601
- 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
3602
- 'class': settings.oClasses.sProcessing
3603
- } )
3604
- .html( settings.oLanguage.sProcessing )
3605
- .insertBefore( settings.nTable )[0];
3606
- }
3607
-
3608
-
3609
- /**
3610
- * Display or hide the processing indicator
3611
- * @param {object} settings dataTables settings object
3612
- * @param {bool} show Show the processing indicator (true) or not (false)
3613
- * @memberof DataTable#oApi
3614
- */
3615
- function _fnProcessingDisplay ( settings, show )
3616
- {
3617
- if ( settings.oFeatures.bProcessing ) {
3618
- $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
3619
- }
3620
-
3621
- _fnCallbackFire( settings, null, 'processing', [settings, show] );
3622
- }
3623
-
3624
- /**
3625
- * Add any control elements for the table - specifically scrolling
3626
- * @param {object} settings dataTables settings object
3627
- * @returns {node} Node to add to the DOM
3628
- * @memberof DataTable#oApi
3629
- */
3630
- function _fnFeatureHtmlTable ( settings )
3631
- {
3632
- var table = $(settings.nTable);
3633
-
3634
- // Add the ARIA grid role to the table
3635
- table.attr( 'role', 'grid' );
3636
-
3637
- // Scrolling from here on in
3638
- var scroll = settings.oScroll;
3639
-
3640
- if ( scroll.sX === '' && scroll.sY === '' ) {
3641
- return settings.nTable;
3642
- }
3643
-
3644
- var scrollX = scroll.sX;
3645
- var scrollY = scroll.sY;
3646
- var classes = settings.oClasses;
3647
- var caption = table.children('caption');
3648
- var captionSide = caption.length ? caption[0]._captionSide : null;
3649
- var headerClone = $( table[0].cloneNode(false) );
3650
- var footerClone = $( table[0].cloneNode(false) );
3651
- var footer = table.children('tfoot');
3652
- var _div = '<div/>';
3653
- var size = function ( s ) {
3654
- return !s ? null : _fnStringToCss( s );
3655
- };
3656
-
3657
- // This is fairly messy, but with x scrolling enabled, if the table has a
3658
- // width attribute, regardless of any width applied using the column width
3659
- // options, the browser will shrink or grow the table as needed to fit into
3660
- // that 100%. That would make the width options useless. So we remove it.
3661
- // This is okay, under the assumption that width:100% is applied to the
3662
- // table in CSS (it is in the default stylesheet) which will set the table
3663
- // width as appropriate (the attribute and css behave differently...)
3664
- if ( scroll.sX && table.attr('width') === '100%' ) {
3665
- table.removeAttr('width');
3666
- }
3667
-
3668
- if ( ! footer.length ) {
3669
- footer = null;
3670
- }
3671
-
3672
- /*
3673
- * The HTML structure that we want to generate in this function is:
3674
- * div - scroller
3675
- * div - scroll head
3676
- * div - scroll head inner
3677
- * table - scroll head table
3678
- * thead - thead
3679
- * div - scroll body
3680
- * table - table (master table)
3681
- * thead - thead clone for sizing
3682
- * tbody - tbody
3683
- * div - scroll foot
3684
- * div - scroll foot inner
3685
- * table - scroll foot table
3686
- * tfoot - tfoot
3687
- */
3688
- var scroller = $( _div, { 'class': classes.sScrollWrapper } )
3689
- .append(
3690
- $(_div, { 'class': classes.sScrollHead } )
3691
- .css( {
3692
- overflow: 'hidden',
3693
- position: 'relative',
3694
- border: 0,
3695
- width: scrollX ? size(scrollX) : '100%'
3696
- } )
3697
- .append(
3698
- $(_div, { 'class': classes.sScrollHeadInner } )
3699
- .css( {
3700
- 'box-sizing': 'content-box',
3701
- width: scroll.sXInner || '100%'
3702
- } )
3703
- .append(
3704
- headerClone
3705
- .removeAttr('id')
3706
- .css( 'margin-left', 0 )
3707
- .append( captionSide === 'top' ? caption : null )
3708
- .append(
3709
- table.children('thead')
3710
- )
3711
- )
3712
- )
3713
- )
3714
- .append(
3715
- $(_div, { 'class': classes.sScrollBody } )
3716
- .css( {
3717
- position: 'relative',
3718
- overflow: 'auto',
3719
- width: size( scrollX )
3720
- } )
3721
- .append( table )
3722
- );
3723
-
3724
- if ( footer ) {
3725
- scroller.append(
3726
- $(_div, { 'class': classes.sScrollFoot } )
3727
- .css( {
3728
- overflow: 'hidden',
3729
- border: 0,
3730
- width: scrollX ? size(scrollX) : '100%'
3731
- } )
3732
- .append(
3733
- $(_div, { 'class': classes.sScrollFootInner } )
3734
- .append(
3735
- footerClone
3736
- .removeAttr('id')
3737
- .css( 'margin-left', 0 )
3738
- .append( captionSide === 'bottom' ? caption : null )
3739
- .append(
3740
- table.children('tfoot')
3741
- )
3742
- )
3743
- )
3744
- );
3745
- }
3746
-
3747
- var children = scroller.children();
3748
- var scrollHead = children[0];
3749
- var scrollBody = children[1];
3750
- var scrollFoot = footer ? children[2] : null;
3751
-
3752
- // When the body is scrolled, then we also want to scroll the headers
3753
- if ( scrollX ) {
3754
- $(scrollBody).on( 'scroll.DT', function (e) {
3755
- var scrollLeft = this.scrollLeft;
3756
-
3757
- scrollHead.scrollLeft = scrollLeft;
3758
-
3759
- if ( footer ) {
3760
- scrollFoot.scrollLeft = scrollLeft;
3761
- }
3762
- } );
3763
- }
3764
-
3765
- $(scrollBody).css(
3766
- scrollY && scroll.bCollapse ? 'max-height' : 'height',
3767
- scrollY
3768
- );
3769
-
3770
- settings.nScrollHead = scrollHead;
3771
- settings.nScrollBody = scrollBody;
3772
- settings.nScrollFoot = scrollFoot;
3773
-
3774
- // On redraw - align columns
3775
- settings.aoDrawCallback.push( {
3776
- "fn": _fnScrollDraw,
3777
- "sName": "scrolling"
3778
- } );
3779
-
3780
- return scroller[0];
3781
- }
3782
-
3783
-
3784
-
3785
- /**
3786
- * Update the header, footer and body tables for resizing - i.e. column
3787
- * alignment.
3788
- *
3789
- * Welcome to the most horrible function DataTables. The process that this
3790
- * function follows is basically:
3791
- * 1. Re-create the table inside the scrolling div
3792
- * 2. Take live measurements from the DOM
3793
- * 3. Apply the measurements to align the columns
3794
- * 4. Clean up
3795
- *
3796
- * @param {object} settings dataTables settings object
3797
- * @memberof DataTable#oApi
3798
- */
3799
- function _fnScrollDraw ( settings )
3800
- {
3801
- // Given that this is such a monster function, a lot of variables are use
3802
- // to try and keep the minimised size as small as possible
3803
- var
3804
- scroll = settings.oScroll,
3805
- scrollX = scroll.sX,
3806
- scrollXInner = scroll.sXInner,
3807
- scrollY = scroll.sY,
3808
- barWidth = scroll.iBarWidth,
3809
- divHeader = $(settings.nScrollHead),
3810
- divHeaderStyle = divHeader[0].style,
3811
- divHeaderInner = divHeader.children('div'),
3812
- divHeaderInnerStyle = divHeaderInner[0].style,
3813
- divHeaderTable = divHeaderInner.children('table'),
3814
- divBodyEl = settings.nScrollBody,
3815
- divBody = $(divBodyEl),
3816
- divBodyStyle = divBodyEl.style,
3817
- divFooter = $(settings.nScrollFoot),
3818
- divFooterInner = divFooter.children('div'),
3819
- divFooterTable = divFooterInner.children('table'),
3820
- header = $(settings.nTHead),
3821
- table = $(settings.nTable),
3822
- tableEl = table[0],
3823
- tableStyle = tableEl.style,
3824
- footer = settings.nTFoot ? $(settings.nTFoot) : null,
3825
- browser = settings.oBrowser,
3826
- ie67 = browser.bScrollOversize,
3827
- headerTrgEls, footerTrgEls,
3828
- headerSrcEls, footerSrcEls,
3829
- headerCopy, footerCopy,
3830
- headerWidths=[], footerWidths=[],
3831
- headerContent=[],
3832
- idx, correction, sanityWidth,
3833
- zeroOut = function(nSizer) {
3834
- var style = nSizer.style;
3835
- style.paddingTop = "0";
3836
- style.paddingBottom = "0";
3837
- style.borderTopWidth = "0";
3838
- style.borderBottomWidth = "0";
3839
- style.height = 0;
3840
- };
3841
-
3842
- /*
3843
- * 1. Re-create the table inside the scrolling div
3844
- */
3845
-
3846
- // Remove the old minimised thead and tfoot elements in the inner table
3847
- table.children('thead, tfoot').remove();
3848
-
3849
- // Clone the current header and footer elements and then place it into the inner table
3850
- headerCopy = header.clone().prependTo( table );
3851
- headerTrgEls = header.find('tr'); // original header is in its own table
3852
- headerSrcEls = headerCopy.find('tr');
3853
- headerCopy.find('th, td').removeAttr('tabindex');
3854
-
3855
- if ( footer ) {
3856
- footerCopy = footer.clone().prependTo( table );
3857
- footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
3858
- footerSrcEls = footerCopy.find('tr');
3859
- }
3860
-
3861
-
3862
- /*
3863
- * 2. Take live measurements from the DOM - do not alter the DOM itself!
3864
- */
3865
-
3866
- // Remove old sizing and apply the calculated column widths
3867
- // Get the unique column headers in the newly created (cloned) header. We want to apply the
3868
- // calculated sizes to this header
3869
- if ( ! scrollX )
3870
- {
3871
- divBodyStyle.width = '100%';
3872
- divHeader[0].style.width = '100%';
3873
- }
3874
-
3875
- $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
3876
- idx = _fnVisibleToColumnIndex( settings, i );
3877
- el.style.width = settings.aoColumns[idx].sWidth;
3878
- } );
3879
-
3880
- if ( footer ) {
3881
- _fnApplyToChildren( function(n) {
3882
- n.style.width = "";
3883
- }, footerSrcEls );
3884
- }
3885
-
3886
- // Size the table as a whole
3887
- sanityWidth = table.outerWidth();
3888
- if ( scrollX === "" ) {
3889
- // No x scrolling
3890
- tableStyle.width = "100%";
3891
-
3892
- // IE7 will make the width of the table when 100% include the scrollbar
3893
- // - which is shouldn't. When there is a scrollbar we need to take this
3894
- // into account.
3895
- if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
3896
- divBody.css('overflow-y') == "scroll")
3897
- ) {
3898
- tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
3899
- }
3900
-
3901
- // Recalculate the sanity width
3902
- sanityWidth = table.outerWidth();
3903
- }
3904
- else if ( scrollXInner !== "" ) {
3905
- // legacy x scroll inner has been given - use it
3906
- tableStyle.width = _fnStringToCss(scrollXInner);
3907
-
3908
- // Recalculate the sanity width
3909
- sanityWidth = table.outerWidth();
3910
- }
3911
-
3912
- // Hidden header should have zero height, so remove padding and borders. Then
3913
- // set the width based on the real headers
3914
-
3915
- // Apply all styles in one pass
3916
- _fnApplyToChildren( zeroOut, headerSrcEls );
3917
-
3918
- // Read all widths in next pass
3919
- _fnApplyToChildren( function(nSizer) {
3920
- headerContent.push( nSizer.innerHTML );
3921
- headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3922
- }, headerSrcEls );
3923
-
3924
- // Apply all widths in final pass
3925
- _fnApplyToChildren( function(nToSize, i) {
3926
- nToSize.style.width = headerWidths[i];
3927
- }, headerTrgEls );
3928
-
3929
- $(headerSrcEls).height(0);
3930
-
3931
- /* Same again with the footer if we have one */
3932
- if ( footer )
3933
- {
3934
- _fnApplyToChildren( zeroOut, footerSrcEls );
3935
-
3936
- _fnApplyToChildren( function(nSizer) {
3937
- footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3938
- }, footerSrcEls );
3939
-
3940
- _fnApplyToChildren( function(nToSize, i) {
3941
- nToSize.style.width = footerWidths[i];
3942
- }, footerTrgEls );
3943
-
3944
- $(footerSrcEls).height(0);
3945
- }
3946
-
3947
-
3948
- /*
3949
- * 3. Apply the measurements
3950
- */
3951
-
3952
- // "Hide" the header and footer that we used for the sizing. We need to keep
3953
- // the content of the cell so that the width applied to the header and body
3954
- // both match, but we want to hide it completely. We want to also fix their
3955
- // width to what they currently are
3956
- _fnApplyToChildren( function(nSizer, i) {
3957
- nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
3958
- nSizer.style.width = headerWidths[i];
3959
- }, headerSrcEls );
3960
-
3961
- if ( footer )
3962
- {
3963
- _fnApplyToChildren( function(nSizer, i) {
3964
- nSizer.innerHTML = "";
3965
- nSizer.style.width = footerWidths[i];
3966
- }, footerSrcEls );
3967
- }
3968
-
3969
- // Sanity check that the table is of a sensible width. If not then we are going to get
3970
- // misalignment - try to prevent this by not allowing the table to shrink below its min width
3971
- if ( table.outerWidth() < sanityWidth )
3972
- {
3973
- // The min width depends upon if we have a vertical scrollbar visible or not */
3974
- correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
3975
- divBody.css('overflow-y') == "scroll")) ?
3976
- sanityWidth+barWidth :
3977
- sanityWidth;
3978
-
3979
- // IE6/7 are a law unto themselves...
3980
- if ( ie67 && (divBodyEl.scrollHeight >
3981
- divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
3982
- ) {
3983
- tableStyle.width = _fnStringToCss( correction-barWidth );
3984
- }
3985
-
3986
- // And give the user a warning that we've stopped the table getting too small
3987
- if ( scrollX === "" || scrollXInner !== "" ) {
3988
- _fnLog( settings, 1, 'Possible column misalignment', 6 );
3989
- }
3990
- }
3991
- else
3992
- {
3993
- correction = '100%';
3994
- }
3995
-
3996
- // Apply to the container elements
3997
- divBodyStyle.width = _fnStringToCss( correction );
3998
- divHeaderStyle.width = _fnStringToCss( correction );
3999
-
4000
- if ( footer ) {
4001
- settings.nScrollFoot.style.width = _fnStringToCss( correction );
4002
- }
4003
-
4004
-
4005
- /*
4006
- * 4. Clean up
4007
- */
4008
- if ( ! scrollY ) {
4009
- /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
4010
- * the scrollbar height from the visible display, rather than adding it on. We need to
4011
- * set the height in order to sort this. Don't want to do it in any other browsers.
4012
- */
4013
- if ( ie67 ) {
4014
- divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
4015
- }
4016
- }
4017
-
4018
- /* Finally set the width's of the header and footer tables */
4019
- var iOuterWidth = table.outerWidth();
4020
- divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
4021
- divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
4022
-
4023
- // Figure out if there are scrollbar present - if so then we need a the header and footer to
4024
- // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
4025
- var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
4026
- var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
4027
- divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
4028
-
4029
- if ( footer ) {
4030
- divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
4031
- divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
4032
- divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
4033
- }
4034
-
4035
- /* Adjust the position of the header in case we loose the y-scrollbar */
4036
- divBody.scroll();
4037
-
4038
- // If sorting or filtering has occurred, jump the scrolling back to the top
4039
- // only if we aren't holding the position
4040
- if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
4041
- divBodyEl.scrollTop = 0;
4042
- }
4043
- }
4044
-
4045
-
4046
-
4047
- /**
4048
- * Apply a given function to the display child nodes of an element array (typically
4049
- * TD children of TR rows
4050
- * @param {function} fn Method to apply to the objects
4051
- * @param array {nodes} an1 List of elements to look through for display children
4052
- * @param array {nodes} an2 Another list (identical structure to the first) - optional
4053
- * @memberof DataTable#oApi
4054
- */
4055
- function _fnApplyToChildren( fn, an1, an2 )
4056
- {
4057
- var index=0, i=0, iLen=an1.length;
4058
- var nNode1, nNode2;
4059
-
4060
- while ( i < iLen ) {
4061
- nNode1 = an1[i].firstChild;
4062
- nNode2 = an2 ? an2[i].firstChild : null;
4063
-
4064
- while ( nNode1 ) {
4065
- if ( nNode1.nodeType === 1 ) {
4066
- if ( an2 ) {
4067
- fn( nNode1, nNode2, index );
4068
- }
4069
- else {
4070
- fn( nNode1, index );
4071
- }
4072
-
4073
- index++;
4074
- }
4075
-
4076
- nNode1 = nNode1.nextSibling;
4077
- nNode2 = an2 ? nNode2.nextSibling : null;
4078
- }
4079
-
4080
- i++;
4081
- }
4082
- }
4083
-
4084
-
4085
-
4086
- var __re_html_remove = /<.*?>/g;
4087
-
4088
-
4089
- /**
4090
- * Calculate the width of columns for the table
4091
- * @param {object} oSettings dataTables settings object
4092
- * @memberof DataTable#oApi
4093
- */
4094
- function _fnCalculateColumnWidths ( oSettings )
4095
- {
4096
- var
4097
- table = oSettings.nTable,
4098
- columns = oSettings.aoColumns,
4099
- scroll = oSettings.oScroll,
4100
- scrollY = scroll.sY,
4101
- scrollX = scroll.sX,
4102
- scrollXInner = scroll.sXInner,
4103
- columnCount = columns.length,
4104
- visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
4105
- headerCells = $('th', oSettings.nTHead),
4106
- tableWidthAttr = table.getAttribute('width'), // from DOM element
4107
- tableContainer = table.parentNode,
4108
- userInputs = false,
4109
- i, column, columnIdx, width, outerWidth,
4110
- browser = oSettings.oBrowser,
4111
- ie67 = browser.bScrollOversize;
4112
-
4113
- var styleWidth = table.style.width;
4114
- if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
4115
- tableWidthAttr = styleWidth;
4116
- }
4117
-
4118
- /* Convert any user input sizes into pixel sizes */
4119
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4120
- column = columns[ visibleColumns[i] ];
4121
-
4122
- if ( column.sWidth !== null ) {
4123
- column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
4124
-
4125
- userInputs = true;
4126
- }
4127
- }
4128
-
4129
- /* If the number of columns in the DOM equals the number that we have to
4130
- * process in DataTables, then we can use the offsets that are created by
4131
- * the web- browser. No custom sizes can be set in order for this to happen,
4132
- * nor scrolling used
4133
- */
4134
- if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
4135
- columnCount == _fnVisbleColumns( oSettings ) &&
4136
- columnCount == headerCells.length
4137
- ) {
4138
- for ( i=0 ; i<columnCount ; i++ ) {
4139
- columns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );
4140
- }
4141
- }
4142
- else
4143
- {
4144
- // Otherwise construct a single row, worst case, table with the widest
4145
- // node in the data, assign any user defined widths, then insert it into
4146
- // the DOM and allow the browser to do all the hard work of calculating
4147
- // table widths
4148
- var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
4149
- .css( 'visibility', 'hidden' )
4150
- .removeAttr( 'id' );
4151
-
4152
- // Clean up the table body
4153
- tmpTable.find('tbody tr').remove();
4154
- var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
4155
-
4156
- // Clone the table header and footer - we can't use the header / footer
4157
- // from the cloned table, since if scrolling is active, the table's
4158
- // real header and footer are contained in different table tags
4159
- tmpTable.find('thead, tfoot').remove();
4160
- tmpTable
4161
- .append( $(oSettings.nTHead).clone() )
4162
- .append( $(oSettings.nTFoot).clone() );
4163
-
4164
- // Remove any assigned widths from the footer (from scrolling)
4165
- tmpTable.find('tfoot th, tfoot td').css('width', '');
4166
-
4167
- // Apply custom sizing to the cloned header
4168
- headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
4169
-
4170
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4171
- column = columns[ visibleColumns[i] ];
4172
-
4173
- headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
4174
- _fnStringToCss( column.sWidthOrig ) :
4175
- '';
4176
- }
4177
-
4178
- // Find the widest cell for each column and put it into the table
4179
- if ( oSettings.aoData.length ) {
4180
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4181
- columnIdx = visibleColumns[i];
4182
- column = columns[ columnIdx ];
4183
-
4184
- $( _fnGetWidestNode( oSettings, columnIdx ) )
4185
- .clone( false )
4186
- .append( column.sContentPadding )
4187
- .appendTo( tr );
4188
- }
4189
- }
4190
-
4191
- // Table has been built, attach to the document so we can work with it.
4192
- // A holding element is used, positioned at the top of the container
4193
- // with minimal height, so it has no effect on if the container scrolls
4194
- // or not. Otherwise it might trigger scrolling when it actually isn't
4195
- // needed
4196
- var holder = $('<div/>').css( scrollX || scrollY ?
4197
- {
4198
- position: 'absolute',
4199
- top: 0,
4200
- left: 0,
4201
- height: 1,
4202
- right: 0,
4203
- overflow: 'hidden'
4204
- } :
4205
- {}
4206
- )
4207
- .append( tmpTable )
4208
- .appendTo( tableContainer );
4209
-
4210
- // When scrolling (X or Y) we want to set the width of the table as
4211
- // appropriate. However, when not scrolling leave the table width as it
4212
- // is. This results in slightly different, but I think correct behaviour
4213
- if ( scrollX && scrollXInner ) {
4214
- tmpTable.width( scrollXInner );
4215
- }
4216
- else if ( scrollX ) {
4217
- tmpTable.css( 'width', 'auto' );
4218
-
4219
- if ( tmpTable.width() < tableContainer.clientWidth ) {
4220
- tmpTable.width( tableContainer.clientWidth );
4221
- }
4222
- }
4223
- else if ( scrollY ) {
4224
- tmpTable.width( tableContainer.clientWidth );
4225
- }
4226
- else if ( tableWidthAttr ) {
4227
- tmpTable.width( tableWidthAttr );
4228
- }
4229
-
4230
- // Browsers need a bit of a hand when a width is assigned to any columns
4231
- // when x-scrolling as they tend to collapse the table to the min-width,
4232
- // even if we sent the column widths. So we need to keep track of what
4233
- // the table width should be by summing the user given values, and the
4234
- // automatic values
4235
- if ( scrollX )
4236
- {
4237
- var total = 0;
4238
-
4239
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4240
- column = columns[ visibleColumns[i] ];
4241
-
4242
- // Much prefer to use getBoundingClientRect due to its sub-pixel
4243
- // resolution, but IE8- do not support the width property.
4244
- outerWidth = browser.bBounding ?
4245
- headerCells[i].getBoundingClientRect().width :
4246
- $(headerCells[i]).outerWidth();
4247
-
4248
- total += column.sWidthOrig === null ?
4249
- outerWidth :
4250
- parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
4251
- }
4252
-
4253
- tmpTable.width( _fnStringToCss( total ) );
4254
- table.style.width = _fnStringToCss( total );
4255
- }
4256
-
4257
- // Get the width of each column in the constructed table
4258
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4259
- column = columns[ visibleColumns[i] ];
4260
- width = $(headerCells[i]).width();
4261
-
4262
- if ( width ) {
4263
- column.sWidth = _fnStringToCss( width );
4264
- }
4265
- }
4266
-
4267
- table.style.width = _fnStringToCss( tmpTable.css('width') );
4268
-
4269
- // Finished with the table - ditch it
4270
- holder.remove();
4271
- }
4272
-
4273
- // If there is a width attr, we want to attach an event listener which
4274
- // allows the table sizing to automatically adjust when the window is
4275
- // resized. Use the width attr rather than CSS, since we can't know if the
4276
- // CSS is a relative value or absolute - DOM read is always px.
4277
- if ( tableWidthAttr ) {
4278
- table.style.width = _fnStringToCss( tableWidthAttr );
4279
- }
4280
-
4281
- if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
4282
- var bindResize = function () {
4283
- $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
4284
- _fnAdjustColumnSizing( oSettings );
4285
- } ) );
4286
- };
4287
-
4288
- // IE6/7 will crash if we bind a resize event handler on page load.
4289
- // To be removed in 1.11 which drops IE6/7 support
4290
- if ( ie67 ) {
4291
- setTimeout( bindResize, 1000 );
4292
- }
4293
- else {
4294
- bindResize();
4295
- }
4296
-
4297
- oSettings._reszEvt = true;
4298
- }
4299
- }
4300
-
4301
-
4302
- /**
4303
- * Throttle the calls to a function. Arguments and context are maintained for
4304
- * the throttled function
4305
- * @param {function} fn Function to be called
4306
- * @param {int} [freq=200] call frequency in mS
4307
- * @returns {function} wrapped function
4308
- * @memberof DataTable#oApi
4309
- */
4310
- function _fnThrottle( fn, freq ) {
4311
- var
4312
- frequency = freq !== undefined ? freq : 200,
4313
- last,
4314
- timer;
4315
-
4316
- return function () {
4317
- var
4318
- that = this,
4319
- now = +new Date(),
4320
- args = arguments;
4321
-
4322
- if ( last && now < last + frequency ) {
4323
- clearTimeout( timer );
4324
-
4325
- timer = setTimeout( function () {
4326
- last = undefined;
4327
- fn.apply( that, args );
4328
- }, frequency );
4329
- }
4330
- else {
4331
- last = now;
4332
- fn.apply( that, args );
4333
- }
4334
- };
4335
- }
4336
-
4337
-
4338
- /**
4339
- * Convert a CSS unit width to pixels (e.g. 2em)
4340
- * @param {string} width width to be converted
4341
- * @param {node} parent parent to get the with for (required for relative widths) - optional
4342
- * @returns {int} width in pixels
4343
- * @memberof DataTable#oApi
4344
- */
4345
- function _fnConvertToWidth ( width, parent )
4346
- {
4347
- if ( ! width ) {
4348
- return 0;
4349
- }
4350
-
4351
- var n = $('<div/>')
4352
- .css( 'width', _fnStringToCss( width ) )
4353
- .appendTo( parent || document.body );
4354
-
4355
- var val = n[0].offsetWidth;
4356
- n.remove();
4357
-
4358
- return val;
4359
- }
4360
-
4361
-
4362
- /**
4363
- * Get the widest node
4364
- * @param {object} settings dataTables settings object
4365
- * @param {int} colIdx column of interest
4366
- * @returns {node} widest table node
4367
- * @memberof DataTable#oApi
4368
- */
4369
- function _fnGetWidestNode( settings, colIdx )
4370
- {
4371
- var idx = _fnGetMaxLenString( settings, colIdx );
4372
- if ( idx < 0 ) {
4373
- return null;
4374
- }
4375
-
4376
- var data = settings.aoData[ idx ];
4377
- return ! data.nTr ? // Might not have been created when deferred rendering
4378
- $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
4379
- data.anCells[ colIdx ];
4380
- }
4381
-
4382
-
4383
- /**
4384
- * Get the maximum strlen for each data column
4385
- * @param {object} settings dataTables settings object
4386
- * @param {int} colIdx column of interest
4387
- * @returns {string} max string length for each column
4388
- * @memberof DataTable#oApi
4389
- */
4390
- function _fnGetMaxLenString( settings, colIdx )
4391
- {
4392
- var s, max=-1, maxIdx = -1;
4393
-
4394
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4395
- s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
4396
- s = s.replace( __re_html_remove, '' );
4397
-
4398
- if ( s.length > max ) {
4399
- max = s.length;
4400
- maxIdx = i;
4401
- }
4402
- }
4403
-
4404
- return maxIdx;
4405
- }
4406
-
4407
-
4408
- /**
4409
- * Append a CSS unit (only if required) to a string
4410
- * @param {string} value to css-ify
4411
- * @returns {string} value with css unit
4412
- * @memberof DataTable#oApi
4413
- */
4414
- function _fnStringToCss( s )
4415
- {
4416
- if ( s === null ) {
4417
- return '0px';
4418
- }
4419
-
4420
- if ( typeof s == 'number' ) {
4421
- return s < 0 ?
4422
- '0px' :
4423
- s+'px';
4424
- }
4425
-
4426
- // Check it has a unit character already
4427
- return s.match(/\d$/) ?
4428
- s+'px' :
4429
- s;
4430
- }
4431
-
4432
-
4433
- /**
4434
- * Get the width of a scroll bar in this browser being used
4435
- * @returns {int} width in pixels
4436
- * @memberof DataTable#oApi
4437
- */
4438
- function _fnScrollBarWidth ()
4439
- {
4440
- // On first run a static variable is set, since this is only needed once.
4441
- // Subsequent runs will just use the previously calculated value
4442
- var width = DataTable.__scrollbarWidth;
4443
-
4444
- if ( width === undefined ) {
4445
- var sizer = $('<p/>').css( {
4446
- position: 'absolute',
4447
- top: 0,
4448
- left: 0,
4449
- width: '100%',
4450
- height: 150,
4451
- padding: 0,
4452
- overflow: 'scroll',
4453
- visibility: 'hidden'
4454
- } )
4455
- .appendTo('body');
4456
-
4457
- width = sizer[0].offsetWidth - sizer[0].clientWidth;
4458
- DataTable.__scrollbarWidth = width;
4459
-
4460
- sizer.remove();
4461
- }
4462
-
4463
- return width;
4464
- }
4465
-
4466
-
4467
-
4468
- function _fnSortFlatten ( settings )
4469
- {
4470
- var
4471
- i, iLen, k, kLen,
4472
- aSort = [],
4473
- aiOrig = [],
4474
- aoColumns = settings.aoColumns,
4475
- aDataSort, iCol, sType, srcCol,
4476
- fixed = settings.aaSortingFixed,
4477
- fixedObj = $.isPlainObject( fixed ),
4478
- nestedSort = [],
4479
- add = function ( a ) {
4480
- if ( a.length && ! $.isArray( a[0] ) ) {
4481
- // 1D array
4482
- nestedSort.push( a );
4483
- }
4484
- else {
4485
- // 2D array
4486
- nestedSort.push.apply( nestedSort, a );
4487
- }
4488
- };
4489
-
4490
- // Build the sort array, with pre-fix and post-fix options if they have been
4491
- // specified
4492
- if ( $.isArray( fixed ) ) {
4493
- add( fixed );
4494
- }
4495
-
4496
- if ( fixedObj && fixed.pre ) {
4497
- add( fixed.pre );
4498
- }
4499
-
4500
- add( settings.aaSorting );
4501
-
4502
- if (fixedObj && fixed.post ) {
4503
- add( fixed.post );
4504
- }
4505
-
4506
- for ( i=0 ; i<nestedSort.length ; i++ )
4507
- {
4508
- srcCol = nestedSort[i][0];
4509
- aDataSort = aoColumns[ srcCol ].aDataSort;
4510
-
4511
- for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
4512
- {
4513
- iCol = aDataSort[k];
4514
- sType = aoColumns[ iCol ].sType || 'string';
4515
-
4516
- if ( nestedSort[i]._idx === undefined ) {
4517
- nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
4518
- }
4519
-
4520
- aSort.push( {
4521
- src: srcCol,
4522
- col: iCol,
4523
- dir: nestedSort[i][1],
4524
- index: nestedSort[i]._idx,
4525
- type: sType,
4526
- formatter: DataTable.ext.type.order[ sType+"-pre" ]
4527
- } );
4528
- }
4529
- }
4530
-
4531
- return aSort;
4532
- }
4533
-
4534
- /**
4535
- * Change the order of the table
4536
- * @param {object} oSettings dataTables settings object
4537
- * @memberof DataTable#oApi
4538
- * @todo This really needs split up!
4539
- */
4540
- function _fnSort ( oSettings )
4541
- {
4542
- var
4543
- i, ien, iLen, j, jLen, k, kLen,
4544
- sDataType, nTh,
4545
- aiOrig = [],
4546
- oExtSort = DataTable.ext.type.order,
4547
- aoData = oSettings.aoData,
4548
- aoColumns = oSettings.aoColumns,
4549
- aDataSort, data, iCol, sType, oSort,
4550
- formatters = 0,
4551
- sortCol,
4552
- displayMaster = oSettings.aiDisplayMaster,
4553
- aSort;
4554
-
4555
- // Resolve any column types that are unknown due to addition or invalidation
4556
- // @todo Can this be moved into a 'data-ready' handler which is called when
4557
- // data is going to be used in the table?
4558
- _fnColumnTypes( oSettings );
4559
-
4560
- aSort = _fnSortFlatten( oSettings );
4561
-
4562
- for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
4563
- sortCol = aSort[i];
4564
-
4565
- // Track if we can use the fast sort algorithm
4566
- if ( sortCol.formatter ) {
4567
- formatters++;
4568
- }
4569
-
4570
- // Load the data needed for the sort, for each cell
4571
- _fnSortData( oSettings, sortCol.col );
4572
- }
4573
-
4574
- /* No sorting required if server-side or no sorting array */
4575
- if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
4576
- {
4577
- // Create a value - key array of the current row positions such that we can use their
4578
- // current position during the sort, if values match, in order to perform stable sorting
4579
- for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
4580
- aiOrig[ displayMaster[i] ] = i;
4581
- }
4582
-
4583
- /* Do the sort - here we want multi-column sorting based on a given data source (column)
4584
- * and sorting function (from oSort) in a certain direction. It's reasonably complex to
4585
- * follow on it's own, but this is what we want (example two column sorting):
4586
- * fnLocalSorting = function(a,b){
4587
- * var iTest;
4588
- * iTest = oSort['string-asc']('data11', 'data12');
4589
- * if (iTest !== 0)
4590
- * return iTest;
4591
- * iTest = oSort['numeric-desc']('data21', 'data22');
4592
- * if (iTest !== 0)
4593
- * return iTest;
4594
- * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
4595
- * }
4596
- * Basically we have a test for each sorting column, if the data in that column is equal,
4597
- * test the next column. If all columns match, then we use a numeric sort on the row
4598
- * positions in the original data array to provide a stable sort.
4599
- *
4600
- * Note - I know it seems excessive to have two sorting methods, but the first is around
4601
- * 15% faster, so the second is only maintained for backwards compatibility with sorting
4602
- * methods which do not have a pre-sort formatting function.
4603
- */
4604
- if ( formatters === aSort.length ) {
4605
- // All sort types have formatting functions
4606
- displayMaster.sort( function ( a, b ) {
4607
- var
4608
- x, y, k, test, sort,
4609
- len=aSort.length,
4610
- dataA = aoData[a]._aSortData,
4611
- dataB = aoData[b]._aSortData;
4612
-
4613
- for ( k=0 ; k<len ; k++ ) {
4614
- sort = aSort[k];
4615
-
4616
- x = dataA[ sort.col ];
4617
- y = dataB[ sort.col ];
4618
-
4619
- test = x<y ? -1 : x>y ? 1 : 0;
4620
- if ( test !== 0 ) {
4621
- return sort.dir === 'asc' ? test : -test;
4622
- }
4623
- }
4624
-
4625
- x = aiOrig[a];
4626
- y = aiOrig[b];
4627
- return x<y ? -1 : x>y ? 1 : 0;
4628
- } );
4629
- }
4630
- else {
4631
- // Depreciated - remove in 1.11 (providing a plug-in option)
4632
- // Not all sort types have formatting methods, so we have to call their sorting
4633
- // methods.
4634
- displayMaster.sort( function ( a, b ) {
4635
- var
4636
- x, y, k, l, test, sort, fn,
4637
- len=aSort.length,
4638
- dataA = aoData[a]._aSortData,
4639
- dataB = aoData[b]._aSortData;
4640
-
4641
- for ( k=0 ; k<len ; k++ ) {
4642
- sort = aSort[k];
4643
-
4644
- x = dataA[ sort.col ];
4645
- y = dataB[ sort.col ];
4646
-
4647
- fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
4648
- test = fn( x, y );
4649
- if ( test !== 0 ) {
4650
- return test;
4651
- }
4652
- }
4653
-
4654
- x = aiOrig[a];
4655
- y = aiOrig[b];
4656
- return x<y ? -1 : x>y ? 1 : 0;
4657
- } );
4658
- }
4659
- }
4660
-
4661
- /* Tell the draw function that we have sorted the data */
4662
- oSettings.bSorted = true;
4663
- }
4664
-
4665
-
4666
- function _fnSortAria ( settings )
4667
- {
4668
- var label;
4669
- var nextSort;
4670
- var columns = settings.aoColumns;
4671
- var aSort = _fnSortFlatten( settings );
4672
- var oAria = settings.oLanguage.oAria;
4673
-
4674
- // ARIA attributes - need to loop all columns, to update all (removing old
4675
- // attributes as needed)
4676
- for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
4677
- {
4678
- var col = columns[i];
4679
- var asSorting = col.asSorting;
4680
- var sTitle = col.sTitle.replace( /<.*?>/g, "" );
4681
- var th = col.nTh;
4682
-
4683
- // IE7 is throwing an error when setting these properties with jQuery's
4684
- // attr() and removeAttr() methods...
4685
- th.removeAttribute('aria-sort');
4686
-
4687
- /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
4688
- if ( col.bSortable ) {
4689
- if ( aSort.length > 0 && aSort[0].col == i ) {
4690
- th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
4691
- nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
4692
- }
4693
- else {
4694
- nextSort = asSorting[0];
4695
- }
4696
-
4697
- label = sTitle + ( nextSort === "asc" ?
4698
- oAria.sSortAscending :
4699
- oAria.sSortDescending
4700
- );
4701
- }
4702
- else {
4703
- label = sTitle;
4704
- }
4705
-
4706
- th.setAttribute('aria-label', label);
4707
- }
4708
- }
4709
-
4710
-
4711
- /**
4712
- * Function to run on user sort request
4713
- * @param {object} settings dataTables settings object
4714
- * @param {node} attachTo node to attach the handler to
4715
- * @param {int} colIdx column sorting index
4716
- * @param {boolean} [append=false] Append the requested sort to the existing
4717
- * sort if true (i.e. multi-column sort)
4718
- * @param {function} [callback] callback function
4719
- * @memberof DataTable#oApi
4720
- */
4721
- function _fnSortListener ( settings, colIdx, append, callback )
4722
- {
4723
- var col = settings.aoColumns[ colIdx ];
4724
- var sorting = settings.aaSorting;
4725
- var asSorting = col.asSorting;
4726
- var nextSortIdx;
4727
- var next = function ( a, overflow ) {
4728
- var idx = a._idx;
4729
- if ( idx === undefined ) {
4730
- idx = $.inArray( a[1], asSorting );
4731
- }
4732
-
4733
- return idx+1 < asSorting.length ?
4734
- idx+1 :
4735
- overflow ?
4736
- null :
4737
- 0;
4738
- };
4739
-
4740
- // Convert to 2D array if needed
4741
- if ( typeof sorting[0] === 'number' ) {
4742
- sorting = settings.aaSorting = [ sorting ];
4743
- }
4744
-
4745
- // If appending the sort then we are multi-column sorting
4746
- if ( append && settings.oFeatures.bSortMulti ) {
4747
- // Are we already doing some kind of sort on this column?
4748
- var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
4749
-
4750
- if ( sortIdx !== -1 ) {
4751
- // Yes, modify the sort
4752
- nextSortIdx = next( sorting[sortIdx], true );
4753
-
4754
- if ( nextSortIdx === null && sorting.length === 1 ) {
4755
- nextSortIdx = 0; // can't remove sorting completely
4756
- }
4757
-
4758
- if ( nextSortIdx === null ) {
4759
- sorting.splice( sortIdx, 1 );
4760
- }
4761
- else {
4762
- sorting[sortIdx][1] = asSorting[ nextSortIdx ];
4763
- sorting[sortIdx]._idx = nextSortIdx;
4764
- }
4765
- }
4766
- else {
4767
- // No sort on this column yet
4768
- sorting.push( [ colIdx, asSorting[0], 0 ] );
4769
- sorting[sorting.length-1]._idx = 0;
4770
- }
4771
- }
4772
- else if ( sorting.length && sorting[0][0] == colIdx ) {
4773
- // Single column - already sorting on this column, modify the sort
4774
- nextSortIdx = next( sorting[0] );
4775
-
4776
- sorting.length = 1;
4777
- sorting[0][1] = asSorting[ nextSortIdx ];
4778
- sorting[0]._idx = nextSortIdx;
4779
- }
4780
- else {
4781
- // Single column - sort only on this column
4782
- sorting.length = 0;
4783
- sorting.push( [ colIdx, asSorting[0] ] );
4784
- sorting[0]._idx = 0;
4785
- }
4786
-
4787
- // Run the sort by calling a full redraw
4788
- _fnReDraw( settings );
4789
-
4790
- // callback used for async user interaction
4791
- if ( typeof callback == 'function' ) {
4792
- callback( settings );
4793
- }
4794
- }
4795
-
4796
-
4797
- /**
4798
- * Attach a sort handler (click) to a node
4799
- * @param {object} settings dataTables settings object
4800
- * @param {node} attachTo node to attach the handler to
4801
- * @param {int} colIdx column sorting index
4802
- * @param {function} [callback] callback function
4803
- * @memberof DataTable#oApi
4804
- */
4805
- function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
4806
- {
4807
- var col = settings.aoColumns[ colIdx ];
4808
-
4809
- _fnBindAction( attachTo, {}, function (e) {
4810
- /* If the column is not sortable - don't to anything */
4811
- if ( col.bSortable === false ) {
4812
- return;
4813
- }
4814
-
4815
- // If processing is enabled use a timeout to allow the processing
4816
- // display to be shown - otherwise to it synchronously
4817
- if ( settings.oFeatures.bProcessing ) {
4818
- _fnProcessingDisplay( settings, true );
4819
-
4820
- setTimeout( function() {
4821
- _fnSortListener( settings, colIdx, e.shiftKey, callback );
4822
-
4823
- // In server-side processing, the draw callback will remove the
4824
- // processing display
4825
- if ( _fnDataSource( settings ) !== 'ssp' ) {
4826
- _fnProcessingDisplay( settings, false );
4827
- }
4828
- }, 0 );
4829
- }
4830
- else {
4831
- _fnSortListener( settings, colIdx, e.shiftKey, callback );
4832
- }
4833
- } );
4834
- }
4835
-
4836
-
4837
- /**
4838
- * Set the sorting classes on table's body, Note: it is safe to call this function
4839
- * when bSort and bSortClasses are false
4840
- * @param {object} oSettings dataTables settings object
4841
- * @memberof DataTable#oApi
4842
- */
4843
- function _fnSortingClasses( settings )
4844
- {
4845
- var oldSort = settings.aLastSort;
4846
- var sortClass = settings.oClasses.sSortColumn;
4847
- var sort = _fnSortFlatten( settings );
4848
- var features = settings.oFeatures;
4849
- var i, ien, colIdx;
4850
-
4851
- if ( features.bSort && features.bSortClasses ) {
4852
- // Remove old sorting classes
4853
- for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
4854
- colIdx = oldSort[i].src;
4855
-
4856
- // Remove column sorting
4857
- $( _pluck( settings.aoData, 'anCells', colIdx ) )
4858
- .removeClass( sortClass + (i<2 ? i+1 : 3) );
4859
- }
4860
-
4861
- // Add new column sorting
4862
- for ( i=0, ien=sort.length ; i<ien ; i++ ) {
4863
- colIdx = sort[i].src;
4864
-
4865
- $( _pluck( settings.aoData, 'anCells', colIdx ) )
4866
- .addClass( sortClass + (i<2 ? i+1 : 3) );
4867
- }
4868
- }
4869
-
4870
- settings.aLastSort = sort;
4871
- }
4872
-
4873
-
4874
- // Get the data to sort a column, be it from cache, fresh (populating the
4875
- // cache), or from a sort formatter
4876
- function _fnSortData( settings, idx )
4877
- {
4878
- // Custom sorting function - provided by the sort data type
4879
- var column = settings.aoColumns[ idx ];
4880
- var customSort = DataTable.ext.order[ column.sSortDataType ];
4881
- var customData;
4882
-
4883
- if ( customSort ) {
4884
- customData = customSort.call( settings.oInstance, settings, idx,
4885
- _fnColumnIndexToVisible( settings, idx )
4886
- );
4887
- }
4888
-
4889
- // Use / populate cache
4890
- var row, cellData;
4891
- var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
4892
-
4893
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4894
- row = settings.aoData[i];
4895
-
4896
- if ( ! row._aSortData ) {
4897
- row._aSortData = [];
4898
- }
4899
-
4900
- if ( ! row._aSortData[idx] || customSort ) {
4901
- cellData = customSort ?
4902
- customData[i] : // If there was a custom sort function, use data from there
4903
- _fnGetCellData( settings, i, idx, 'sort' );
4904
-
4905
- row._aSortData[ idx ] = formatter ?
4906
- formatter( cellData ) :
4907
- cellData;
4908
- }
4909
- }
4910
- }
4911
-
4912
-
4913
-
4914
- /**
4915
- * Save the state of a table
4916
- * @param {object} oSettings dataTables settings object
4917
- * @memberof DataTable#oApi
4918
- */
4919
- function _fnSaveState ( settings )
4920
- {
4921
- if ( !settings.oFeatures.bStateSave || settings.bDestroying )
4922
- {
4923
- return;
4924
- }
4925
-
4926
- /* Store the interesting variables */
4927
- var state = {
4928
- time: +new Date(),
4929
- start: settings._iDisplayStart,
4930
- length: settings._iDisplayLength,
4931
- order: $.extend( true, [], settings.aaSorting ),
4932
- search: _fnSearchToCamel( settings.oPreviousSearch ),
4933
- columns: $.map( settings.aoColumns, function ( col, i ) {
4934
- return {
4935
- visible: col.bVisible,
4936
- search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
4937
- };
4938
- } )
4939
- };
4940
-
4941
- _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
4942
-
4943
- settings.oSavedState = state;
4944
- settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
4945
- }
4946
-
4947
-
4948
- /**
4949
- * Attempt to load a saved table state
4950
- * @param {object} oSettings dataTables settings object
4951
- * @param {object} oInit DataTables init object so we can override settings
4952
- * @memberof DataTable#oApi
4953
- */
4954
- function _fnLoadState ( settings, oInit )
4955
- {
4956
- var i, ien;
4957
- var columns = settings.aoColumns;
4958
-
4959
- if ( ! settings.oFeatures.bStateSave ) {
4960
- return;
4961
- }
4962
-
4963
- var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
4964
- if ( ! state || ! state.time ) {
4965
- return;
4966
- }
4967
-
4968
- /* Allow custom and plug-in manipulation functions to alter the saved data set and
4969
- * cancelling of loading by returning false
4970
- */
4971
- var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
4972
- if ( $.inArray( false, abStateLoad ) !== -1 ) {
4973
- return;
4974
- }
4975
-
4976
- /* Reject old data */
4977
- var duration = settings.iStateDuration;
4978
- if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
4979
- return;
4980
- }
4981
-
4982
- // Number of columns have changed - all bets are off, no restore of settings
4983
- if ( columns.length !== state.columns.length ) {
4984
- return;
4985
- }
4986
-
4987
- // Store the saved state so it might be accessed at any time
4988
- settings.oLoadedState = $.extend( true, {}, state );
4989
-
4990
- // Restore key features - todo - for 1.11 this needs to be done by
4991
- // subscribed events
4992
- if ( state.start !== undefined ) {
4993
- settings._iDisplayStart = state.start;
4994
- settings.iInitDisplayStart = state.start;
4995
- }
4996
- if ( state.length !== undefined ) {
4997
- settings._iDisplayLength = state.length;
4998
- }
4999
-
5000
- // Order
5001
- if ( state.order !== undefined ) {
5002
- settings.aaSorting = [];
5003
- $.each( state.order, function ( i, col ) {
5004
- settings.aaSorting.push( col[0] >= columns.length ?
5005
- [ 0, col[1] ] :
5006
- col
5007
- );
5008
- } );
5009
- }
5010
-
5011
- // Search
5012
- if ( state.search !== undefined ) {
5013
- $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
5014
- }
5015
-
5016
- // Columns
5017
- for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
5018
- var col = state.columns[i];
5019
-
5020
- // Visibility
5021
- if ( col.visible !== undefined ) {
5022
- columns[i].bVisible = col.visible;
5023
- }
5024
-
5025
- // Search
5026
- if ( col.search !== undefined ) {
5027
- $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
5028
- }
5029
- }
5030
-
5031
- _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
5032
- }
5033
-
5034
-
5035
- /**
5036
- * Return the settings object for a particular table
5037
- * @param {node} table table we are using as a dataTable
5038
- * @returns {object} Settings object - or null if not found
5039
- * @memberof DataTable#oApi
5040
- */
5041
- function _fnSettingsFromNode ( table )
5042
- {
5043
- var settings = DataTable.settings;
5044
- var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
5045
-
5046
- return idx !== -1 ?
5047
- settings[ idx ] :
5048
- null;
5049
- }
5050
-
5051
-
5052
- /**
5053
- * Log an error message
5054
- * @param {object} settings dataTables settings object
5055
- * @param {int} level log error messages, or display them to the user
5056
- * @param {string} msg error message
5057
- * @param {int} tn Technical note id to get more information about the error.
5058
- * @memberof DataTable#oApi
5059
- */
5060
- function _fnLog( settings, level, msg, tn )
5061
- {
5062
- msg = 'DataTables warning: '+
5063
- (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
5064
-
5065
- if ( tn ) {
5066
- msg += '. For more information about this error, please see '+
5067
- 'http://datatables.net/tn/'+tn;
5068
- }
5069
-
5070
- if ( ! level ) {
5071
- // Backwards compatibility pre 1.10
5072
- var ext = DataTable.ext;
5073
- var type = ext.sErrMode || ext.errMode;
5074
-
5075
- if ( settings ) {
5076
- _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
5077
- }
5078
-
5079
- if ( type == 'alert' ) {
5080
- alert( msg );
5081
- }
5082
- else if ( type == 'throw' ) {
5083
- throw new Error(msg);
5084
- }
5085
- else if ( typeof type == 'function' ) {
5086
- type( settings, tn, msg );
5087
- }
5088
- }
5089
- else if ( window.console && console.log ) {
5090
- console.log( msg );
5091
- }
5092
- }
5093
-
5094
-
5095
- /**
5096
- * See if a property is defined on one object, if so assign it to the other object
5097
- * @param {object} ret target object
5098
- * @param {object} src source object
5099
- * @param {string} name property
5100
- * @param {string} [mappedName] name to map too - optional, name used if not given
5101
- * @memberof DataTable#oApi
5102
- */
5103
- function _fnMap( ret, src, name, mappedName )
5104
- {
5105
- if ( $.isArray( name ) ) {
5106
- $.each( name, function (i, val) {
5107
- if ( $.isArray( val ) ) {
5108
- _fnMap( ret, src, val[0], val[1] );
5109
- }
5110
- else {
5111
- _fnMap( ret, src, val );
5112
- }
5113
- } );
5114
-
5115
- return;
5116
- }
5117
-
5118
- if ( mappedName === undefined ) {
5119
- mappedName = name;
5120
- }
5121
-
5122
- if ( src[name] !== undefined ) {
5123
- ret[mappedName] = src[name];
5124
- }
5125
- }
5126
-
5127
-
5128
- /**
5129
- * Extend objects - very similar to jQuery.extend, but deep copy objects, and
5130
- * shallow copy arrays. The reason we need to do this, is that we don't want to
5131
- * deep copy array init values (such as aaSorting) since the dev wouldn't be
5132
- * able to override them, but we do want to deep copy arrays.
5133
- * @param {object} out Object to extend
5134
- * @param {object} extender Object from which the properties will be applied to
5135
- * out
5136
- * @param {boolean} breakRefs If true, then arrays will be sliced to take an
5137
- * independent copy with the exception of the `data` or `aaData` parameters
5138
- * if they are present. This is so you can pass in a collection to
5139
- * DataTables and have that used as your data source without breaking the
5140
- * references
5141
- * @returns {object} out Reference, just for convenience - out === the return.
5142
- * @memberof DataTable#oApi
5143
- * @todo This doesn't take account of arrays inside the deep copied objects.
5144
- */
5145
- function _fnExtend( out, extender, breakRefs )
5146
- {
5147
- var val;
5148
-
5149
- for ( var prop in extender ) {
5150
- if ( extender.hasOwnProperty(prop) ) {
5151
- val = extender[prop];
5152
-
5153
- if ( $.isPlainObject( val ) ) {
5154
- if ( ! $.isPlainObject( out[prop] ) ) {
5155
- out[prop] = {};
5156
- }
5157
- $.extend( true, out[prop], val );
5158
- }
5159
- else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
5160
- out[prop] = val.slice();
5161
- }
5162
- else {
5163
- out[prop] = val;
5164
- }
5165
- }
5166
- }
5167
-
5168
- return out;
5169
- }
5170
-
5171
-
5172
- /**
5173
- * Bind an event handers to allow a click or return key to activate the callback.
5174
- * This is good for accessibility since a return on the keyboard will have the
5175
- * same effect as a click, if the element has focus.
5176
- * @param {element} n Element to bind the action to
5177
- * @param {object} oData Data object to pass to the triggered function
5178
- * @param {function} fn Callback function for when the event is triggered
5179
- * @memberof DataTable#oApi
5180
- */
5181
- function _fnBindAction( n, oData, fn )
5182
- {
5183
- $(n)
5184
- .bind( 'click.DT', oData, function (e) {
5185
- n.blur(); // Remove focus outline for mouse users
5186
- fn(e);
5187
- } )
5188
- .bind( 'keypress.DT', oData, function (e){
5189
- if ( e.which === 13 ) {
5190
- e.preventDefault();
5191
- fn(e);
5192
- }
5193
- } )
5194
- .bind( 'selectstart.DT', function () {
5195
- /* Take the brutal approach to cancelling text selection */
5196
- return false;
5197
- } );
5198
- }
5199
-
5200
-
5201
- /**
5202
- * Register a callback function. Easily allows a callback function to be added to
5203
- * an array store of callback functions that can then all be called together.
5204
- * @param {object} oSettings dataTables settings object
5205
- * @param {string} sStore Name of the array storage for the callbacks in oSettings
5206
- * @param {function} fn Function to be called back
5207
- * @param {string} sName Identifying name for the callback (i.e. a label)
5208
- * @memberof DataTable#oApi
5209
- */
5210
- function _fnCallbackReg( oSettings, sStore, fn, sName )
5211
- {
5212
- if ( fn )
5213
- {
5214
- oSettings[sStore].push( {
5215
- "fn": fn,
5216
- "sName": sName
5217
- } );
5218
- }
5219
- }
5220
-
5221
-
5222
- /**
5223
- * Fire callback functions and trigger events. Note that the loop over the
5224
- * callback array store is done backwards! Further note that you do not want to
5225
- * fire off triggers in time sensitive applications (for example cell creation)
5226
- * as its slow.
5227
- * @param {object} settings dataTables settings object
5228
- * @param {string} callbackArr Name of the array storage for the callbacks in
5229
- * oSettings
5230
- * @param {string} eventName Name of the jQuery custom event to trigger. If
5231
- * null no trigger is fired
5232
- * @param {array} args Array of arguments to pass to the callback function /
5233
- * trigger
5234
- * @memberof DataTable#oApi
5235
- */
5236
- function _fnCallbackFire( settings, callbackArr, eventName, args )
5237
- {
5238
- var ret = [];
5239
-
5240
- if ( callbackArr ) {
5241
- ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
5242
- return val.fn.apply( settings.oInstance, args );
5243
- } );
5244
- }
5245
-
5246
- if ( eventName !== null ) {
5247
- var e = $.Event( eventName+'.dt' );
5248
-
5249
- $(settings.nTable).trigger( e, args );
5250
-
5251
- ret.push( e.result );
5252
- }
5253
-
5254
- return ret;
5255
- }
5256
-
5257
-
5258
- function _fnLengthOverflow ( settings )
5259
- {
5260
- var
5261
- start = settings._iDisplayStart,
5262
- end = settings.fnDisplayEnd(),
5263
- len = settings._iDisplayLength;
5264
-
5265
- /* If we have space to show extra rows (backing up from the end point - then do so */
5266
- if ( start >= end )
5267
- {
5268
- start = end - len;
5269
- }
5270
-
5271
- // Keep the start record on the current page
5272
- start -= (start % len);
5273
-
5274
- if ( len === -1 || start < 0 )
5275
- {
5276
- start = 0;
5277
- }
5278
-
5279
- settings._iDisplayStart = start;
5280
- }
5281
-
5282
-
5283
- function _fnRenderer( settings, type )
5284
- {
5285
- var renderer = settings.renderer;
5286
- var host = DataTable.ext.renderer[type];
5287
-
5288
- if ( $.isPlainObject( renderer ) && renderer[type] ) {
5289
- // Specific renderer for this type. If available use it, otherwise use
5290
- // the default.
5291
- return host[renderer[type]] || host._;
5292
- }
5293
- else if ( typeof renderer === 'string' ) {
5294
- // Common renderer - if there is one available for this type use it,
5295
- // otherwise use the default
5296
- return host[renderer] || host._;
5297
- }
5298
-
5299
- // Use the default
5300
- return host._;
5301
- }
5302
-
5303
-
5304
- /**
5305
- * Detect the data source being used for the table. Used to simplify the code
5306
- * a little (ajax) and to make it compress a little smaller.
5307
- *
5308
- * @param {object} settings dataTables settings object
5309
- * @returns {string} Data source
5310
- * @memberof DataTable#oApi
5311
- */
5312
- function _fnDataSource ( settings )
5313
- {
5314
- if ( settings.oFeatures.bServerSide ) {
5315
- return 'ssp';
5316
- }
5317
- else if ( settings.ajax || settings.sAjaxSource ) {
5318
- return 'ajax';
5319
- }
5320
- return 'dom';
5321
- }
5322
-
5323
-
5324
- DataTable = function( options )
5325
- {
5326
- /**
5327
- * Perform a jQuery selector action on the table's TR elements (from the tbody) and
5328
- * return the resulting jQuery object.
5329
- * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5330
- * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5331
- * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
5332
- * criterion ("applied") or all TR elements (i.e. no filter).
5333
- * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
5334
- * Can be either 'current', whereby the current sorting of the table is used, or
5335
- * 'original' whereby the original order the data was read into the table is used.
5336
- * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5337
- * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5338
- * 'current' and filter is 'applied', regardless of what they might be given as.
5339
- * @returns {object} jQuery object, filtered by the given selector.
5340
- * @dtopt API
5341
- * @deprecated Since v1.10
5342
- *
5343
- * @example
5344
- * $(document).ready(function() {
5345
- * var oTable = $('#example').dataTable();
5346
- *
5347
- * // Highlight every second row
5348
- * oTable.$('tr:odd').css('backgroundColor', 'blue');
5349
- * } );
5350
- *
5351
- * @example
5352
- * $(document).ready(function() {
5353
- * var oTable = $('#example').dataTable();
5354
- *
5355
- * // Filter to rows with 'Webkit' in them, add a background colour and then
5356
- * // remove the filter, thus highlighting the 'Webkit' rows only.
5357
- * oTable.fnFilter('Webkit');
5358
- * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
5359
- * oTable.fnFilter('');
5360
- * } );
5361
- */
5362
- this.$ = function ( sSelector, oOpts )
5363
- {
5364
- return this.api(true).$( sSelector, oOpts );
5365
- };
5366
-
5367
-
5368
- /**
5369
- * Almost identical to $ in operation, but in this case returns the data for the matched
5370
- * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
5371
- * rather than any descendants, so the data can be obtained for the row/cell. If matching
5372
- * rows are found, the data returned is the original data array/object that was used to
5373
- * create the row (or a generated array if from a DOM source).
5374
- *
5375
- * This method is often useful in-combination with $ where both functions are given the
5376
- * same parameters and the array indexes will match identically.
5377
- * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5378
- * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5379
- * @param {string} [oOpts.filter=none] Select elements that meet the current filter
5380
- * criterion ("applied") or all elements (i.e. no filter).
5381
- * @param {string} [oOpts.order=current] Order of the data in the processed array.
5382
- * Can be either 'current', whereby the current sorting of the table is used, or
5383
- * 'original' whereby the original order the data was read into the table is used.
5384
- * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5385
- * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5386
- * 'current' and filter is 'applied', regardless of what they might be given as.
5387
- * @returns {array} Data for the matched elements. If any elements, as a result of the
5388
- * selector, were not TR, TD or TH elements in the DataTable, they will have a null
5389
- * entry in the array.
5390
- * @dtopt API
5391
- * @deprecated Since v1.10
5392
- *
5393
- * @example
5394
- * $(document).ready(function() {
5395
- * var oTable = $('#example').dataTable();
5396
- *
5397
- * // Get the data from the first row in the table
5398
- * var data = oTable._('tr:first');
5399
- *
5400
- * // Do something useful with the data
5401
- * alert( "First cell is: "+data[0] );
5402
- * } );
5403
- *
5404
- * @example
5405
- * $(document).ready(function() {
5406
- * var oTable = $('#example').dataTable();
5407
- *
5408
- * // Filter to 'Webkit' and get all data for
5409
- * oTable.fnFilter('Webkit');
5410
- * var data = oTable._('tr', {"search": "applied"});
5411
- *
5412
- * // Do something with the data
5413
- * alert( data.length+" rows matched the search" );
5414
- * } );
5415
- */
5416
- this._ = function ( sSelector, oOpts )
5417
- {
5418
- return this.api(true).rows( sSelector, oOpts ).data();
5419
- };
5420
-
5421
-
5422
- /**
5423
- * Create a DataTables Api instance, with the currently selected tables for
5424
- * the Api's context.
5425
- * @param {boolean} [traditional=false] Set the API instance's context to be
5426
- * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
5427
- * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
5428
- * or if all tables captured in the jQuery object should be used.
5429
- * @return {DataTables.Api}
5430
- */
5431
- this.api = function ( traditional )
5432
- {
5433
- return traditional ?
5434
- new _Api(
5435
- _fnSettingsFromNode( this[ _ext.iApiIndex ] )
5436
- ) :
5437
- new _Api( this );
5438
- };
5439
-
5440
-
5441
- /**
5442
- * Add a single new row or multiple rows of data to the table. Please note
5443
- * that this is suitable for client-side processing only - if you are using
5444
- * server-side processing (i.e. "bServerSide": true), then to add data, you
5445
- * must add it to the data source, i.e. the server-side, through an Ajax call.
5446
- * @param {array|object} data The data to be added to the table. This can be:
5447
- * <ul>
5448
- * <li>1D array of data - add a single row with the data provided</li>
5449
- * <li>2D array of arrays - add multiple rows in a single call</li>
5450
- * <li>object - data object when using <i>mData</i></li>
5451
- * <li>array of objects - multiple data objects when using <i>mData</i></li>
5452
- * </ul>
5453
- * @param {bool} [redraw=true] redraw the table or not
5454
- * @returns {array} An array of integers, representing the list of indexes in
5455
- * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
5456
- * the table.
5457
- * @dtopt API
5458
- * @deprecated Since v1.10
5459
- *
5460
- * @example
5461
- * // Global var for counter
5462
- * var giCount = 2;
5463
- *
5464
- * $(document).ready(function() {
5465
- * $('#example').dataTable();
5466
- * } );
5467
- *
5468
- * function fnClickAddRow() {
5469
- * $('#example').dataTable().fnAddData( [
5470
- * giCount+".1",
5471
- * giCount+".2",
5472
- * giCount+".3",
5473
- * giCount+".4" ]
5474
- * );
5475
- *
5476
- * giCount++;
5477
- * }
5478
- */
5479
- this.fnAddData = function( data, redraw )
5480
- {
5481
- var api = this.api( true );
5482
-
5483
- /* Check if we want to add multiple rows or not */
5484
- var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
5485
- api.rows.add( data ) :
5486
- api.row.add( data );
5487
-
5488
- if ( redraw === undefined || redraw ) {
5489
- api.draw();
5490
- }
5491
-
5492
- return rows.flatten().toArray();
5493
- };
5494
-
5495
-
5496
- /**
5497
- * This function will make DataTables recalculate the column sizes, based on the data
5498
- * contained in the table and the sizes applied to the columns (in the DOM, CSS or
5499
- * through the sWidth parameter). This can be useful when the width of the table's
5500
- * parent element changes (for example a window resize).
5501
- * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
5502
- * @dtopt API
5503
- * @deprecated Since v1.10
5504
- *
5505
- * @example
5506
- * $(document).ready(function() {
5507
- * var oTable = $('#example').dataTable( {
5508
- * "sScrollY": "200px",
5509
- * "bPaginate": false
5510
- * } );
5511
- *
5512
- * $(window).bind('resize', function () {
5513
- * oTable.fnAdjustColumnSizing();
5514
- * } );
5515
- * } );
5516
- */
5517
- this.fnAdjustColumnSizing = function ( bRedraw )
5518
- {
5519
- var api = this.api( true ).columns.adjust();
5520
- var settings = api.settings()[0];
5521
- var scroll = settings.oScroll;
5522
-
5523
- if ( bRedraw === undefined || bRedraw ) {
5524
- api.draw( false );
5525
- }
5526
- else if ( scroll.sX !== "" || scroll.sY !== "" ) {
5527
- /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
5528
- _fnScrollDraw( settings );
5529
- }
5530
- };
5531
-
5532
-
5533
- /**
5534
- * Quickly and simply clear a table
5535
- * @param {bool} [bRedraw=true] redraw the table or not
5536
- * @dtopt API
5537
- * @deprecated Since v1.10
5538
- *
5539
- * @example
5540
- * $(document).ready(function() {
5541
- * var oTable = $('#example').dataTable();
5542
- *
5543
- * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
5544
- * oTable.fnClearTable();
5545
- * } );
5546
- */
5547
- this.fnClearTable = function( bRedraw )
5548
- {
5549
- var api = this.api( true ).clear();
5550
-
5551
- if ( bRedraw === undefined || bRedraw ) {
5552
- api.draw();
5553
- }
5554
- };
5555
-
5556
-
5557
- /**
5558
- * The exact opposite of 'opening' a row, this function will close any rows which
5559
- * are currently 'open'.
5560
- * @param {node} nTr the table row to 'close'
5561
- * @returns {int} 0 on success, or 1 if failed (can't find the row)
5562
- * @dtopt API
5563
- * @deprecated Since v1.10
5564
- *
5565
- * @example
5566
- * $(document).ready(function() {
5567
- * var oTable;
5568
- *
5569
- * // 'open' an information row when a row is clicked on
5570
- * $('#example tbody tr').click( function () {
5571
- * if ( oTable.fnIsOpen(this) ) {
5572
- * oTable.fnClose( this );
5573
- * } else {
5574
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5575
- * }
5576
- * } );
5577
- *
5578
- * oTable = $('#example').dataTable();
5579
- * } );
5580
- */
5581
- this.fnClose = function( nTr )
5582
- {
5583
- this.api( true ).row( nTr ).child.hide();
5584
- };
5585
-
5586
-
5587
- /**
5588
- * Remove a row for the table
5589
- * @param {mixed} target The index of the row from aoData to be deleted, or
5590
- * the TR element you want to delete
5591
- * @param {function|null} [callBack] Callback function
5592
- * @param {bool} [redraw=true] Redraw the table or not
5593
- * @returns {array} The row that was deleted
5594
- * @dtopt API
5595
- * @deprecated Since v1.10
5596
- *
5597
- * @example
5598
- * $(document).ready(function() {
5599
- * var oTable = $('#example').dataTable();
5600
- *
5601
- * // Immediately remove the first row
5602
- * oTable.fnDeleteRow( 0 );
5603
- * } );
5604
- */
5605
- this.fnDeleteRow = function( target, callback, redraw )
5606
- {
5607
- var api = this.api( true );
5608
- var rows = api.rows( target );
5609
- var settings = rows.settings()[0];
5610
- var data = settings.aoData[ rows[0][0] ];
5611
-
5612
- rows.remove();
5613
-
5614
- if ( callback ) {
5615
- callback.call( this, settings, data );
5616
- }
5617
-
5618
- if ( redraw === undefined || redraw ) {
5619
- api.draw();
5620
- }
5621
-
5622
- return data;
5623
- };
5624
-
5625
-
5626
- /**
5627
- * Restore the table to it's original state in the DOM by removing all of DataTables
5628
- * enhancements, alterations to the DOM structure of the table and event listeners.
5629
- * @param {boolean} [remove=false] Completely remove the table from the DOM
5630
- * @dtopt API
5631
- * @deprecated Since v1.10
5632
- *
5633
- * @example
5634
- * $(document).ready(function() {
5635
- * // This example is fairly pointless in reality, but shows how fnDestroy can be used
5636
- * var oTable = $('#example').dataTable();
5637
- * oTable.fnDestroy();
5638
- * } );
5639
- */
5640
- this.fnDestroy = function ( remove )
5641
- {
5642
- this.api( true ).destroy( remove );
5643
- };
5644
-
5645
-
5646
- /**
5647
- * Redraw the table
5648
- * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
5649
- * @dtopt API
5650
- * @deprecated Since v1.10
5651
- *
5652
- * @example
5653
- * $(document).ready(function() {
5654
- * var oTable = $('#example').dataTable();
5655
- *
5656
- * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
5657
- * oTable.fnDraw();
5658
- * } );
5659
- */
5660
- this.fnDraw = function( complete )
5661
- {
5662
- // Note that this isn't an exact match to the old call to _fnDraw - it takes
5663
- // into account the new data, but can hold position.
5664
- this.api( true ).draw( complete );
5665
- };
5666
-
5667
-
5668
- /**
5669
- * Filter the input based on data
5670
- * @param {string} sInput String to filter the table on
5671
- * @param {int|null} [iColumn] Column to limit filtering to
5672
- * @param {bool} [bRegex=false] Treat as regular expression or not
5673
- * @param {bool} [bSmart=true] Perform smart filtering or not
5674
- * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
5675
- * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
5676
- * @dtopt API
5677
- * @deprecated Since v1.10
5678
- *
5679
- * @example
5680
- * $(document).ready(function() {
5681
- * var oTable = $('#example').dataTable();
5682
- *
5683
- * // Sometime later - filter...
5684
- * oTable.fnFilter( 'test string' );
5685
- * } );
5686
- */
5687
- this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
5688
- {
5689
- var api = this.api( true );
5690
-
5691
- if ( iColumn === null || iColumn === undefined ) {
5692
- api.search( sInput, bRegex, bSmart, bCaseInsensitive );
5693
- }
5694
- else {
5695
- api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
5696
- }
5697
-
5698
- api.draw();
5699
- };
5700
-
5701
-
5702
- /**
5703
- * Get the data for the whole table, an individual row or an individual cell based on the
5704
- * provided parameters.
5705
- * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
5706
- * a TR node then the data source for the whole row will be returned. If given as a
5707
- * TD/TH cell node then iCol will be automatically calculated and the data for the
5708
- * cell returned. If given as an integer, then this is treated as the aoData internal
5709
- * data index for the row (see fnGetPosition) and the data for that row used.
5710
- * @param {int} [col] Optional column index that you want the data of.
5711
- * @returns {array|object|string} If mRow is undefined, then the data for all rows is
5712
- * returned. If mRow is defined, just data for that row, and is iCol is
5713
- * defined, only data for the designated cell is returned.
5714
- * @dtopt API
5715
- * @deprecated Since v1.10
5716
- *
5717
- * @example
5718
- * // Row data
5719
- * $(document).ready(function() {
5720
- * oTable = $('#example').dataTable();
5721
- *
5722
- * oTable.$('tr').click( function () {
5723
- * var data = oTable.fnGetData( this );
5724
- * // ... do something with the array / object of data for the row
5725
- * } );
5726
- * } );
5727
- *
5728
- * @example
5729
- * // Individual cell data
5730
- * $(document).ready(function() {
5731
- * oTable = $('#example').dataTable();
5732
- *
5733
- * oTable.$('td').click( function () {
5734
- * var sData = oTable.fnGetData( this );
5735
- * alert( 'The cell clicked on had the value of '+sData );
5736
- * } );
5737
- * } );
5738
- */
5739
- this.fnGetData = function( src, col )
5740
- {
5741
- var api = this.api( true );
5742
-
5743
- if ( src !== undefined ) {
5744
- var type = src.nodeName ? src.nodeName.toLowerCase() : '';
5745
-
5746
- return col !== undefined || type == 'td' || type == 'th' ?
5747
- api.cell( src, col ).data() :
5748
- api.row( src ).data() || null;
5749
- }
5750
-
5751
- return api.data().toArray();
5752
- };
5753
-
5754
-
5755
- /**
5756
- * Get an array of the TR nodes that are used in the table's body. Note that you will
5757
- * typically want to use the '$' API method in preference to this as it is more
5758
- * flexible.
5759
- * @param {int} [iRow] Optional row index for the TR element you want
5760
- * @returns {array|node} If iRow is undefined, returns an array of all TR elements
5761
- * in the table's body, or iRow is defined, just the TR element requested.
5762
- * @dtopt API
5763
- * @deprecated Since v1.10
5764
- *
5765
- * @example
5766
- * $(document).ready(function() {
5767
- * var oTable = $('#example').dataTable();
5768
- *
5769
- * // Get the nodes from the table
5770
- * var nNodes = oTable.fnGetNodes( );
5771
- * } );
5772
- */
5773
- this.fnGetNodes = function( iRow )
5774
- {
5775
- var api = this.api( true );
5776
-
5777
- return iRow !== undefined ?
5778
- api.row( iRow ).node() :
5779
- api.rows().nodes().flatten().toArray();
5780
- };
5781
-
5782
-
5783
- /**
5784
- * Get the array indexes of a particular cell from it's DOM element
5785
- * and column index including hidden columns
5786
- * @param {node} node this can either be a TR, TD or TH in the table's body
5787
- * @returns {int} If nNode is given as a TR, then a single index is returned, or
5788
- * if given as a cell, an array of [row index, column index (visible),
5789
- * column index (all)] is given.
5790
- * @dtopt API
5791
- * @deprecated Since v1.10
5792
- *
5793
- * @example
5794
- * $(document).ready(function() {
5795
- * $('#example tbody td').click( function () {
5796
- * // Get the position of the current data from the node
5797
- * var aPos = oTable.fnGetPosition( this );
5798
- *
5799
- * // Get the data array for this row
5800
- * var aData = oTable.fnGetData( aPos[0] );
5801
- *
5802
- * // Update the data array and return the value
5803
- * aData[ aPos[1] ] = 'clicked';
5804
- * this.innerHTML = 'clicked';
5805
- * } );
5806
- *
5807
- * // Init DataTables
5808
- * oTable = $('#example').dataTable();
5809
- * } );
5810
- */
5811
- this.fnGetPosition = function( node )
5812
- {
5813
- var api = this.api( true );
5814
- var nodeName = node.nodeName.toUpperCase();
5815
-
5816
- if ( nodeName == 'TR' ) {
5817
- return api.row( node ).index();
5818
- }
5819
- else if ( nodeName == 'TD' || nodeName == 'TH' ) {
5820
- var cell = api.cell( node ).index();
5821
-
5822
- return [
5823
- cell.row,
5824
- cell.columnVisible,
5825
- cell.column
5826
- ];
5827
- }
5828
- return null;
5829
- };
5830
-
5831
-
5832
- /**
5833
- * Check to see if a row is 'open' or not.
5834
- * @param {node} nTr the table row to check
5835
- * @returns {boolean} true if the row is currently open, false otherwise
5836
- * @dtopt API
5837
- * @deprecated Since v1.10
5838
- *
5839
- * @example
5840
- * $(document).ready(function() {
5841
- * var oTable;
5842
- *
5843
- * // 'open' an information row when a row is clicked on
5844
- * $('#example tbody tr').click( function () {
5845
- * if ( oTable.fnIsOpen(this) ) {
5846
- * oTable.fnClose( this );
5847
- * } else {
5848
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5849
- * }
5850
- * } );
5851
- *
5852
- * oTable = $('#example').dataTable();
5853
- * } );
5854
- */
5855
- this.fnIsOpen = function( nTr )
5856
- {
5857
- return this.api( true ).row( nTr ).child.isShown();
5858
- };
5859
-
5860
-
5861
- /**
5862
- * This function will place a new row directly after a row which is currently
5863
- * on display on the page, with the HTML contents that is passed into the
5864
- * function. This can be used, for example, to ask for confirmation that a
5865
- * particular record should be deleted.
5866
- * @param {node} nTr The table row to 'open'
5867
- * @param {string|node|jQuery} mHtml The HTML to put into the row
5868
- * @param {string} sClass Class to give the new TD cell
5869
- * @returns {node} The row opened. Note that if the table row passed in as the
5870
- * first parameter, is not found in the table, this method will silently
5871
- * return.
5872
- * @dtopt API
5873
- * @deprecated Since v1.10
5874
- *
5875
- * @example
5876
- * $(document).ready(function() {
5877
- * var oTable;
5878
- *
5879
- * // 'open' an information row when a row is clicked on
5880
- * $('#example tbody tr').click( function () {
5881
- * if ( oTable.fnIsOpen(this) ) {
5882
- * oTable.fnClose( this );
5883
- * } else {
5884
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5885
- * }
5886
- * } );
5887
- *
5888
- * oTable = $('#example').dataTable();
5889
- * } );
5890
- */
5891
- this.fnOpen = function( nTr, mHtml, sClass )
5892
- {
5893
- return this.api( true )
5894
- .row( nTr )
5895
- .child( mHtml, sClass )
5896
- .show()
5897
- .child()[0];
5898
- };
5899
-
5900
-
5901
- /**
5902
- * Change the pagination - provides the internal logic for pagination in a simple API
5903
- * function. With this function you can have a DataTables table go to the next,
5904
- * previous, first or last pages.
5905
- * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
5906
- * or page number to jump to (integer), note that page 0 is the first page.
5907
- * @param {bool} [bRedraw=true] Redraw the table or not
5908
- * @dtopt API
5909
- * @deprecated Since v1.10
5910
- *
5911
- * @example
5912
- * $(document).ready(function() {
5913
- * var oTable = $('#example').dataTable();
5914
- * oTable.fnPageChange( 'next' );
5915
- * } );
5916
- */
5917
- this.fnPageChange = function ( mAction, bRedraw )
5918
- {
5919
- var api = this.api( true ).page( mAction );
5920
-
5921
- if ( bRedraw === undefined || bRedraw ) {
5922
- api.draw(false);
5923
- }
5924
- };
5925
-
5926
-
5927
- /**
5928
- * Show a particular column
5929
- * @param {int} iCol The column whose display should be changed
5930
- * @param {bool} bShow Show (true) or hide (false) the column
5931
- * @param {bool} [bRedraw=true] Redraw the table or not
5932
- * @dtopt API
5933
- * @deprecated Since v1.10
5934
- *
5935
- * @example
5936
- * $(document).ready(function() {
5937
- * var oTable = $('#example').dataTable();
5938
- *
5939
- * // Hide the second column after initialisation
5940
- * oTable.fnSetColumnVis( 1, false );
5941
- * } );
5942
- */
5943
- this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
5944
- {
5945
- var api = this.api( true ).column( iCol ).visible( bShow );
5946
-
5947
- if ( bRedraw === undefined || bRedraw ) {
5948
- api.columns.adjust().draw();
5949
- }
5950
- };
5951
-
5952
-
5953
- /**
5954
- * Get the settings for a particular table for external manipulation
5955
- * @returns {object} DataTables settings object. See
5956
- * {@link DataTable.models.oSettings}
5957
- * @dtopt API
5958
- * @deprecated Since v1.10
5959
- *
5960
- * @example
5961
- * $(document).ready(function() {
5962
- * var oTable = $('#example').dataTable();
5963
- * var oSettings = oTable.fnSettings();
5964
- *
5965
- * // Show an example parameter from the settings
5966
- * alert( oSettings._iDisplayStart );
5967
- * } );
5968
- */
5969
- this.fnSettings = function()
5970
- {
5971
- return _fnSettingsFromNode( this[_ext.iApiIndex] );
5972
- };
5973
-
5974
-
5975
- /**
5976
- * Sort the table by a particular column
5977
- * @param {int} iCol the data index to sort on. Note that this will not match the
5978
- * 'display index' if you have hidden data entries
5979
- * @dtopt API
5980
- * @deprecated Since v1.10
5981
- *
5982
- * @example
5983
- * $(document).ready(function() {
5984
- * var oTable = $('#example').dataTable();
5985
- *
5986
- * // Sort immediately with columns 0 and 1
5987
- * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
5988
- * } );
5989
- */
5990
- this.fnSort = function( aaSort )
5991
- {
5992
- this.api( true ).order( aaSort ).draw();
5993
- };
5994
-
5995
-
5996
- /**
5997
- * Attach a sort listener to an element for a given column
5998
- * @param {node} nNode the element to attach the sort listener to
5999
- * @param {int} iColumn the column that a click on this node will sort on
6000
- * @param {function} [fnCallback] callback function when sort is run
6001
- * @dtopt API
6002
- * @deprecated Since v1.10
6003
- *
6004
- * @example
6005
- * $(document).ready(function() {
6006
- * var oTable = $('#example').dataTable();
6007
- *
6008
- * // Sort on column 1, when 'sorter' is clicked on
6009
- * oTable.fnSortListener( document.getElementById('sorter'), 1 );
6010
- * } );
6011
- */
6012
- this.fnSortListener = function( nNode, iColumn, fnCallback )
6013
- {
6014
- this.api( true ).order.listener( nNode, iColumn, fnCallback );
6015
- };
6016
-
6017
-
6018
- /**
6019
- * Update a table cell or row - this method will accept either a single value to
6020
- * update the cell with, an array of values with one element for each column or
6021
- * an object in the same format as the original data source. The function is
6022
- * self-referencing in order to make the multi column updates easier.
6023
- * @param {object|array|string} mData Data to update the cell/row with
6024
- * @param {node|int} mRow TR element you want to update or the aoData index
6025
- * @param {int} [iColumn] The column to update, give as null or undefined to
6026
- * update a whole row.
6027
- * @param {bool} [bRedraw=true] Redraw the table or not
6028
- * @param {bool} [bAction=true] Perform pre-draw actions or not
6029
- * @returns {int} 0 on success, 1 on error
6030
- * @dtopt API
6031
- * @deprecated Since v1.10
6032
- *
6033
- * @example
6034
- * $(document).ready(function() {
6035
- * var oTable = $('#example').dataTable();
6036
- * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
6037
- * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
6038
- * } );
6039
- */
6040
- this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
6041
- {
6042
- var api = this.api( true );
6043
-
6044
- if ( iColumn === undefined || iColumn === null ) {
6045
- api.row( mRow ).data( mData );
6046
- }
6047
- else {
6048
- api.cell( mRow, iColumn ).data( mData );
6049
- }
6050
-
6051
- if ( bAction === undefined || bAction ) {
6052
- api.columns.adjust();
6053
- }
6054
-
6055
- if ( bRedraw === undefined || bRedraw ) {
6056
- api.draw();
6057
- }
6058
- return 0;
6059
- };
6060
-
6061
-
6062
- /**
6063
- * Provide a common method for plug-ins to check the version of DataTables being used, in order
6064
- * to ensure compatibility.
6065
- * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
6066
- * formats "X" and "X.Y" are also acceptable.
6067
- * @returns {boolean} true if this version of DataTables is greater or equal to the required
6068
- * version, or false if this version of DataTales is not suitable
6069
- * @method
6070
- * @dtopt API
6071
- * @deprecated Since v1.10
6072
- *
6073
- * @example
6074
- * $(document).ready(function() {
6075
- * var oTable = $('#example').dataTable();
6076
- * alert( oTable.fnVersionCheck( '1.9.0' ) );
6077
- * } );
6078
- */
6079
- this.fnVersionCheck = _ext.fnVersionCheck;
6080
-
6081
-
6082
- var _that = this;
6083
- var emptyInit = options === undefined;
6084
- var len = this.length;
6085
-
6086
- if ( emptyInit ) {
6087
- options = {};
6088
- }
6089
-
6090
- this.oApi = this.internal = _ext.internal;
6091
-
6092
- // Extend with old style plug-in API methods
6093
- for ( var fn in DataTable.ext.internal ) {
6094
- if ( fn ) {
6095
- this[fn] = _fnExternApiFunc(fn);
6096
- }
6097
- }
6098
-
6099
- this.each(function() {
6100
- // For each initialisation we want to give it a clean initialisation
6101
- // object that can be bashed around
6102
- var o = {};
6103
- var oInit = len > 1 ? // optimisation for single table case
6104
- _fnExtend( o, options, true ) :
6105
- options;
6106
-
6107
- /*global oInit,_that,emptyInit*/
6108
- var i=0, iLen, j, jLen, k, kLen;
6109
- var sId = this.getAttribute( 'id' );
6110
- var bInitHandedOff = false;
6111
- var defaults = DataTable.defaults;
6112
- var $this = $(this);
6113
-
6114
-
6115
- /* Sanity check */
6116
- if ( this.nodeName.toLowerCase() != 'table' )
6117
- {
6118
- _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
6119
- return;
6120
- }
6121
-
6122
- /* Backwards compatibility for the defaults */
6123
- _fnCompatOpts( defaults );
6124
- _fnCompatCols( defaults.column );
6125
-
6126
- /* Convert the camel-case defaults to Hungarian */
6127
- _fnCamelToHungarian( defaults, defaults, true );
6128
- _fnCamelToHungarian( defaults.column, defaults.column, true );
6129
-
6130
- /* Setting up the initialisation object */
6131
- _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
6132
-
6133
-
6134
-
6135
- /* Check to see if we are re-initialising a table */
6136
- var allSettings = DataTable.settings;
6137
- for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
6138
- {
6139
- var s = allSettings[i];
6140
-
6141
- /* Base check on table node */
6142
- if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
6143
- {
6144
- var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
6145
- var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
6146
-
6147
- if ( emptyInit || bRetrieve )
6148
- {
6149
- return s.oInstance;
6150
- }
6151
- else if ( bDestroy )
6152
- {
6153
- s.oInstance.fnDestroy();
6154
- break;
6155
- }
6156
- else
6157
- {
6158
- _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
6159
- return;
6160
- }
6161
- }
6162
-
6163
- /* If the element we are initialising has the same ID as a table which was previously
6164
- * initialised, but the table nodes don't match (from before) then we destroy the old
6165
- * instance by simply deleting it. This is under the assumption that the table has been
6166
- * destroyed by other methods. Anyone using non-id selectors will need to do this manually
6167
- */
6168
- if ( s.sTableId == this.id )
6169
- {
6170
- allSettings.splice( i, 1 );
6171
- break;
6172
- }
6173
- }
6174
-
6175
- /* Ensure the table has an ID - required for accessibility */
6176
- if ( sId === null || sId === "" )
6177
- {
6178
- sId = "DataTables_Table_"+(DataTable.ext._unique++);
6179
- this.id = sId;
6180
- }
6181
-
6182
- /* Create the settings object for this table and set some of the default parameters */
6183
- var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
6184
- "sDestroyWidth": $this[0].style.width,
6185
- "sInstance": sId,
6186
- "sTableId": sId
6187
- } );
6188
- oSettings.nTable = this;
6189
- oSettings.oApi = _that.internal;
6190
- oSettings.oInit = oInit;
6191
-
6192
- allSettings.push( oSettings );
6193
-
6194
- // Need to add the instance after the instance after the settings object has been added
6195
- // to the settings array, so we can self reference the table instance if more than one
6196
- oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
6197
-
6198
- // Backwards compatibility, before we apply all the defaults
6199
- _fnCompatOpts( oInit );
6200
-
6201
- if ( oInit.oLanguage )
6202
- {
6203
- _fnLanguageCompat( oInit.oLanguage );
6204
- }
6205
-
6206
- // If the length menu is given, but the init display length is not, use the length menu
6207
- if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
6208
- {
6209
- oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
6210
- oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
6211
- }
6212
-
6213
- // Apply the defaults and init options to make a single init object will all
6214
- // options defined from defaults and instance options.
6215
- oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
6216
-
6217
-
6218
- // Map the initialisation options onto the settings object
6219
- _fnMap( oSettings.oFeatures, oInit, [
6220
- "bPaginate",
6221
- "bLengthChange",
6222
- "bFilter",
6223
- "bSort",
6224
- "bSortMulti",
6225
- "bInfo",
6226
- "bProcessing",
6227
- "bAutoWidth",
6228
- "bSortClasses",
6229
- "bServerSide",
6230
- "bDeferRender"
6231
- ] );
6232
- _fnMap( oSettings, oInit, [
6233
- "asStripeClasses",
6234
- "ajax",
6235
- "fnServerData",
6236
- "fnFormatNumber",
6237
- "sServerMethod",
6238
- "aaSorting",
6239
- "aaSortingFixed",
6240
- "aLengthMenu",
6241
- "sPaginationType",
6242
- "sAjaxSource",
6243
- "sAjaxDataProp",
6244
- "iStateDuration",
6245
- "sDom",
6246
- "bSortCellsTop",
6247
- "iTabIndex",
6248
- "fnStateLoadCallback",
6249
- "fnStateSaveCallback",
6250
- "renderer",
6251
- "searchDelay",
6252
- "rowId",
6253
- [ "iCookieDuration", "iStateDuration" ], // backwards compat
6254
- [ "oSearch", "oPreviousSearch" ],
6255
- [ "aoSearchCols", "aoPreSearchCols" ],
6256
- [ "iDisplayLength", "_iDisplayLength" ],
6257
- [ "bJQueryUI", "bJUI" ]
6258
- ] );
6259
- _fnMap( oSettings.oScroll, oInit, [
6260
- [ "sScrollX", "sX" ],
6261
- [ "sScrollXInner", "sXInner" ],
6262
- [ "sScrollY", "sY" ],
6263
- [ "bScrollCollapse", "bCollapse" ]
6264
- ] );
6265
- _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
6266
-
6267
- /* Callback functions which are array driven */
6268
- _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
6269
- _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
6270
- _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
6271
- _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
6272
- _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
6273
- _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
6274
- _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
6275
- _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
6276
- _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
6277
- _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
6278
- _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
6279
-
6280
- oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
6281
-
6282
- var oClasses = oSettings.oClasses;
6283
-
6284
- // @todo Remove in 1.11
6285
- if ( oInit.bJQueryUI )
6286
- {
6287
- /* Use the JUI classes object for display. You could clone the oStdClasses object if
6288
- * you want to have multiple tables with multiple independent classes
6289
- */
6290
- $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
6291
-
6292
- if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
6293
- {
6294
- /* Set the DOM to use a layout suitable for jQuery UI's theming */
6295
- oSettings.sDom = '<"H"lfr>t<"F"ip>';
6296
- }
6297
-
6298
- if ( ! oSettings.renderer ) {
6299
- oSettings.renderer = 'jqueryui';
6300
- }
6301
- else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
6302
- oSettings.renderer.header = 'jqueryui';
6303
- }
6304
- }
6305
- else
6306
- {
6307
- $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
6308
- }
6309
- $this.addClass( oClasses.sTable );
6310
-
6311
- /* Calculate the scroll bar width and cache it for use later on */
6312
- if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
6313
- {
6314
- oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
6315
- }
6316
-
6317
- if ( oSettings.iInitDisplayStart === undefined )
6318
- {
6319
- /* Display start point, taking into account the save saving */
6320
- oSettings.iInitDisplayStart = oInit.iDisplayStart;
6321
- oSettings._iDisplayStart = oInit.iDisplayStart;
6322
- }
6323
-
6324
- if ( oInit.iDeferLoading !== null )
6325
- {
6326
- oSettings.bDeferLoading = true;
6327
- var tmp = $.isArray( oInit.iDeferLoading );
6328
- oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
6329
- oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
6330
- }
6331
-
6332
- /* Language definitions */
6333
- var oLanguage = oSettings.oLanguage;
6334
- $.extend( true, oLanguage, oInit.oLanguage );
6335
-
6336
- if ( oLanguage.sUrl !== "" )
6337
- {
6338
- /* Get the language definitions from a file - because this Ajax call makes the language
6339
- * get async to the remainder of this function we use bInitHandedOff to indicate that
6340
- * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
6341
- */
6342
- $.ajax( {
6343
- dataType: 'json',
6344
- url: oLanguage.sUrl,
6345
- success: function ( json ) {
6346
- _fnLanguageCompat( json );
6347
- _fnCamelToHungarian( defaults.oLanguage, json );
6348
- $.extend( true, oLanguage, json );
6349
- _fnInitialise( oSettings );
6350
- },
6351
- error: function () {
6352
- // Error occurred loading language file, continue on as best we can
6353
- _fnInitialise( oSettings );
6354
- }
6355
- } );
6356
- bInitHandedOff = true;
6357
- }
6358
-
6359
- /*
6360
- * Stripes
6361
- */
6362
- if ( oInit.asStripeClasses === null )
6363
- {
6364
- oSettings.asStripeClasses =[
6365
- oClasses.sStripeOdd,
6366
- oClasses.sStripeEven
6367
- ];
6368
- }
6369
-
6370
- /* Remove row stripe classes if they are already on the table row */
6371
- var stripeClasses = oSettings.asStripeClasses;
6372
- var rowOne = $this.children('tbody').find('tr').eq(0);
6373
- if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
6374
- return rowOne.hasClass(el);
6375
- } ) ) !== -1 ) {
6376
- $('tbody tr', this).removeClass( stripeClasses.join(' ') );
6377
- oSettings.asDestroyStripes = stripeClasses.slice();
6378
- }
6379
-
6380
- /*
6381
- * Columns
6382
- * See if we should load columns automatically or use defined ones
6383
- */
6384
- var anThs = [];
6385
- var aoColumnsInit;
6386
- var nThead = this.getElementsByTagName('thead');
6387
- if ( nThead.length !== 0 )
6388
- {
6389
- _fnDetectHeader( oSettings.aoHeader, nThead[0] );
6390
- anThs = _fnGetUniqueThs( oSettings );
6391
- }
6392
-
6393
- /* If not given a column array, generate one with nulls */
6394
- if ( oInit.aoColumns === null )
6395
- {
6396
- aoColumnsInit = [];
6397
- for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
6398
- {
6399
- aoColumnsInit.push( null );
6400
- }
6401
- }
6402
- else
6403
- {
6404
- aoColumnsInit = oInit.aoColumns;
6405
- }
6406
-
6407
- /* Add the columns */
6408
- for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
6409
- {
6410
- _fnAddColumn( oSettings, anThs ? anThs[i] : null );
6411
- }
6412
-
6413
- /* Apply the column definitions */
6414
- _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
6415
- _fnColumnOptions( oSettings, iCol, oDef );
6416
- } );
6417
-
6418
- /* HTML5 attribute detection - build an mData object automatically if the
6419
- * attributes are found
6420
- */
6421
- if ( rowOne.length ) {
6422
- var a = function ( cell, name ) {
6423
- return cell.getAttribute( 'data-'+name ) !== null ? name : null;
6424
- };
6425
-
6426
- $.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {
6427
- var col = oSettings.aoColumns[i];
6428
-
6429
- if ( col.mData === i ) {
6430
- var sort = a( cell, 'sort' ) || a( cell, 'order' );
6431
- var filter = a( cell, 'filter' ) || a( cell, 'search' );
6432
-
6433
- if ( sort !== null || filter !== null ) {
6434
- col.mData = {
6435
- _: i+'.display',
6436
- sort: sort !== null ? i+'.@data-'+sort : undefined,
6437
- type: sort !== null ? i+'.@data-'+sort : undefined,
6438
- filter: filter !== null ? i+'.@data-'+filter : undefined
6439
- };
6440
-
6441
- _fnColumnOptions( oSettings, i );
6442
- }
6443
- }
6444
- } );
6445
- }
6446
-
6447
- var features = oSettings.oFeatures;
6448
-
6449
- /* Must be done after everything which can be overridden by the state saving! */
6450
- if ( oInit.bStateSave )
6451
- {
6452
- features.bStateSave = true;
6453
- _fnLoadState( oSettings, oInit );
6454
- _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
6455
- }
6456
-
6457
-
6458
- /*
6459
- * Sorting
6460
- * @todo For modularisation (1.11) this needs to do into a sort start up handler
6461
- */
6462
-
6463
- // If aaSorting is not defined, then we use the first indicator in asSorting
6464
- // in case that has been altered, so the default sort reflects that option
6465
- if ( oInit.aaSorting === undefined )
6466
- {
6467
- var sorting = oSettings.aaSorting;
6468
- for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
6469
- {
6470
- sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
6471
- }
6472
- }
6473
-
6474
- /* Do a first pass on the sorting classes (allows any size changes to be taken into
6475
- * account, and also will apply sorting disabled classes if disabled
6476
- */
6477
- _fnSortingClasses( oSettings );
6478
-
6479
- if ( features.bSort )
6480
- {
6481
- _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6482
- if ( oSettings.bSorted ) {
6483
- var aSort = _fnSortFlatten( oSettings );
6484
- var sortedColumns = {};
6485
-
6486
- $.each( aSort, function (i, val) {
6487
- sortedColumns[ val.src ] = val.dir;
6488
- } );
6489
-
6490
- _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
6491
- _fnSortAria( oSettings );
6492
- }
6493
- } );
6494
- }
6495
-
6496
- _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6497
- if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
6498
- _fnSortingClasses( oSettings );
6499
- }
6500
- }, 'sc' );
6501
-
6502
-
6503
- /*
6504
- * Final init
6505
- * Cache the header, body and footer as required, creating them if needed
6506
- */
6507
-
6508
- /* Browser support detection */
6509
- _fnBrowserDetect( oSettings );
6510
-
6511
- // Work around for Webkit bug 83867 - store the caption-side before removing from doc
6512
- var captions = $this.children('caption').each( function () {
6513
- this._captionSide = $this.css('caption-side');
6514
- } );
6515
-
6516
- var thead = $this.children('thead');
6517
- if ( thead.length === 0 )
6518
- {
6519
- thead = $('<thead/>').appendTo(this);
6520
- }
6521
- oSettings.nTHead = thead[0];
6522
-
6523
- var tbody = $this.children('tbody');
6524
- if ( tbody.length === 0 )
6525
- {
6526
- tbody = $('<tbody/>').appendTo(this);
6527
- }
6528
- oSettings.nTBody = tbody[0];
6529
-
6530
- var tfoot = $this.children('tfoot');
6531
- if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
6532
- {
6533
- // If we are a scrolling table, and no footer has been given, then we need to create
6534
- // a tfoot element for the caption element to be appended to
6535
- tfoot = $('<tfoot/>').appendTo(this);
6536
- }
6537
-
6538
- if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
6539
- $this.addClass( oClasses.sNoFooter );
6540
- }
6541
- else if ( tfoot.length > 0 ) {
6542
- oSettings.nTFoot = tfoot[0];
6543
- _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
6544
- }
6545
-
6546
- /* Check if there is data passing into the constructor */
6547
- if ( oInit.aaData )
6548
- {
6549
- for ( i=0 ; i<oInit.aaData.length ; i++ )
6550
- {
6551
- _fnAddData( oSettings, oInit.aaData[ i ] );
6552
- }
6553
- }
6554
- else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
6555
- {
6556
- /* Grab the data from the page - only do this when deferred loading or no Ajax
6557
- * source since there is no point in reading the DOM data if we are then going
6558
- * to replace it with Ajax data
6559
- */
6560
- _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
6561
- }
6562
-
6563
- /* Copy the data index array */
6564
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
6565
-
6566
- /* Initialisation complete - table can be drawn */
6567
- oSettings.bInitialised = true;
6568
-
6569
- /* Check if we need to initialise the table (it might not have been handed off to the
6570
- * language processor)
6571
- */
6572
- if ( bInitHandedOff === false )
6573
- {
6574
- _fnInitialise( oSettings );
6575
- }
6576
- } );
6577
- _that = null;
6578
- return this;
6579
- };
6580
-
6581
-
6582
-
6583
- /**
6584
- * Computed structure of the DataTables API, defined by the options passed to
6585
- * `DataTable.Api.register()` when building the API.
6586
- *
6587
- * The structure is built in order to speed creation and extension of the Api
6588
- * objects since the extensions are effectively pre-parsed.
6589
- *
6590
- * The array is an array of objects with the following structure, where this
6591
- * base array represents the Api prototype base:
6592
- *
6593
- * [
6594
- * {
6595
- * name: 'data' -- string - Property name
6596
- * val: function () {}, -- function - Api method (or undefined if just an object
6597
- * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
6598
- * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
6599
- * },
6600
- * {
6601
- * name: 'row'
6602
- * val: {},
6603
- * methodExt: [ ... ],
6604
- * propExt: [
6605
- * {
6606
- * name: 'data'
6607
- * val: function () {},
6608
- * methodExt: [ ... ],
6609
- * propExt: [ ... ]
6610
- * },
6611
- * ...
6612
- * ]
6613
- * }
6614
- * ]
6615
- *
6616
- * @type {Array}
6617
- * @ignore
6618
- */
6619
- var __apiStruct = [];
6620
-
6621
-
6622
- /**
6623
- * `Array.prototype` reference.
6624
- *
6625
- * @type object
6626
- * @ignore
6627
- */
6628
- var __arrayProto = Array.prototype;
6629
-
6630
-
6631
- /**
6632
- * Abstraction for `context` parameter of the `Api` constructor to allow it to
6633
- * take several different forms for ease of use.
6634
- *
6635
- * Each of the input parameter types will be converted to a DataTables settings
6636
- * object where possible.
6637
- *
6638
- * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
6639
- * of:
6640
- *
6641
- * * `string` - jQuery selector. Any DataTables' matching the given selector
6642
- * with be found and used.
6643
- * * `node` - `TABLE` node which has already been formed into a DataTable.
6644
- * * `jQuery` - A jQuery object of `TABLE` nodes.
6645
- * * `object` - DataTables settings object
6646
- * * `DataTables.Api` - API instance
6647
- * @return {array|null} Matching DataTables settings objects. `null` or
6648
- * `undefined` is returned if no matching DataTable is found.
6649
- * @ignore
6650
- */
6651
- var _toSettings = function ( mixed )
6652
- {
6653
- var idx, jq;
6654
- var settings = DataTable.settings;
6655
- var tables = $.map( settings, function (el, i) {
6656
- return el.nTable;
6657
- } );
6658
-
6659
- if ( ! mixed ) {
6660
- return [];
6661
- }
6662
- else if ( mixed.nTable && mixed.oApi ) {
6663
- // DataTables settings object
6664
- return [ mixed ];
6665
- }
6666
- else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6667
- // Table node
6668
- idx = $.inArray( mixed, tables );
6669
- return idx !== -1 ? [ settings[idx] ] : null;
6670
- }
6671
- else if ( mixed && typeof mixed.settings === 'function' ) {
6672
- return mixed.settings().toArray();
6673
- }
6674
- else if ( typeof mixed === 'string' ) {
6675
- // jQuery selector
6676
- jq = $(mixed);
6677
- }
6678
- else if ( mixed instanceof $ ) {
6679
- // jQuery object (also DataTables instance)
6680
- jq = mixed;
6681
- }
6682
-
6683
- if ( jq ) {
6684
- return jq.map( function(i) {
6685
- idx = $.inArray( this, tables );
6686
- return idx !== -1 ? settings[idx] : null;
6687
- } ).toArray();
6688
- }
6689
- };
6690
-
6691
-
6692
- /**
6693
- * DataTables API class - used to control and interface with one or more
6694
- * DataTables enhanced tables.
6695
- *
6696
- * The API class is heavily based on jQuery, presenting a chainable interface
6697
- * that you can use to interact with tables. Each instance of the API class has
6698
- * a "context" - i.e. the tables that it will operate on. This could be a single
6699
- * table, all tables on a page or a sub-set thereof.
6700
- *
6701
- * Additionally the API is designed to allow you to easily work with the data in
6702
- * the tables, retrieving and manipulating it as required. This is done by
6703
- * presenting the API class as an array like interface. The contents of the
6704
- * array depend upon the actions requested by each method (for example
6705
- * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6706
- * return an array of objects or arrays depending upon your table's
6707
- * configuration). The API object has a number of array like methods (`push`,
6708
- * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6709
- * `unique` etc) to assist your working with the data held in a table.
6710
- *
6711
- * Most methods (those which return an Api instance) are chainable, which means
6712
- * the return from a method call also has all of the methods available that the
6713
- * top level object had. For example, these two calls are equivalent:
6714
- *
6715
- * // Not chained
6716
- * api.row.add( {...} );
6717
- * api.draw();
6718
- *
6719
- * // Chained
6720
- * api.row.add( {...} ).draw();
6721
- *
6722
- * @class DataTable.Api
6723
- * @param {array|object|string|jQuery} context DataTable identifier. This is
6724
- * used to define which DataTables enhanced tables this API will operate on.
6725
- * Can be one of:
6726
- *
6727
- * * `string` - jQuery selector. Any DataTables' matching the given selector
6728
- * with be found and used.
6729
- * * `node` - `TABLE` node which has already been formed into a DataTable.
6730
- * * `jQuery` - A jQuery object of `TABLE` nodes.
6731
- * * `object` - DataTables settings object
6732
- * @param {array} [data] Data to initialise the Api instance with.
6733
- *
6734
- * @example
6735
- * // Direct initialisation during DataTables construction
6736
- * var api = $('#example').DataTable();
6737
- *
6738
- * @example
6739
- * // Initialisation using a DataTables jQuery object
6740
- * var api = $('#example').dataTable().api();
6741
- *
6742
- * @example
6743
- * // Initialisation as a constructor
6744
- * var api = new $.fn.DataTable.Api( 'table.dataTable' );
6745
- */
6746
- _Api = function ( context, data )
6747
- {
6748
- if ( ! (this instanceof _Api) ) {
6749
- return new _Api( context, data );
6750
- }
6751
-
6752
- var settings = [];
6753
- var ctxSettings = function ( o ) {
6754
- var a = _toSettings( o );
6755
- if ( a ) {
6756
- settings.push.apply( settings, a );
6757
- }
6758
- };
6759
-
6760
- if ( $.isArray( context ) ) {
6761
- for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6762
- ctxSettings( context[i] );
6763
- }
6764
- }
6765
- else {
6766
- ctxSettings( context );
6767
- }
6768
-
6769
- // Remove duplicates
6770
- this.context = _unique( settings );
6771
-
6772
- // Initial data
6773
- if ( data ) {
6774
- this.push.apply( this, data.toArray ? data.toArray() : data );
6775
- }
6776
-
6777
- // selector
6778
- this.selector = {
6779
- rows: null,
6780
- cols: null,
6781
- opts: null
6782
- };
6783
-
6784
- _Api.extend( this, this, __apiStruct );
6785
- };
6786
-
6787
- DataTable.Api = _Api;
6788
-
6789
- _Api.prototype = /** @lends DataTables.Api */{
6790
- any: function ()
6791
- {
6792
- return this.count() !== 0;
6793
- },
6794
-
6795
-
6796
- concat: __arrayProto.concat,
6797
-
6798
-
6799
- context: [], // array of table settings objects
6800
-
6801
-
6802
- count: function ()
6803
- {
6804
- return this.flatten().length;
6805
- },
6806
-
6807
-
6808
- each: function ( fn )
6809
- {
6810
- for ( var i=0, ien=this.length ; i<ien; i++ ) {
6811
- fn.call( this, this[i], i, this );
6812
- }
6813
-
6814
- return this;
6815
- },
6816
-
6817
-
6818
- eq: function ( idx )
6819
- {
6820
- var ctx = this.context;
6821
-
6822
- return ctx.length > idx ?
6823
- new _Api( ctx[idx], this[idx] ) :
6824
- null;
6825
- },
6826
-
6827
-
6828
- filter: function ( fn )
6829
- {
6830
- var a = [];
6831
-
6832
- if ( __arrayProto.filter ) {
6833
- a = __arrayProto.filter.call( this, fn, this );
6834
- }
6835
- else {
6836
- // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6837
- for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6838
- if ( fn.call( this, this[i], i, this ) ) {
6839
- a.push( this[i] );
6840
- }
6841
- }
6842
- }
6843
-
6844
- return new _Api( this.context, a );
6845
- },
6846
-
6847
-
6848
- flatten: function ()
6849
- {
6850
- var a = [];
6851
- return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
6852
- },
6853
-
6854
-
6855
- join: __arrayProto.join,
6856
-
6857
-
6858
- indexOf: __arrayProto.indexOf || function (obj, start)
6859
- {
6860
- for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
6861
- if ( this[i] === obj ) {
6862
- return i;
6863
- }
6864
- }
6865
- return -1;
6866
- },
6867
-
6868
- iterator: function ( flatten, type, fn, alwaysNew ) {
6869
- var
6870
- a = [], ret,
6871
- i, ien, j, jen,
6872
- context = this.context,
6873
- rows, items, item,
6874
- selector = this.selector;
6875
-
6876
- // Argument shifting
6877
- if ( typeof flatten === 'string' ) {
6878
- alwaysNew = fn;
6879
- fn = type;
6880
- type = flatten;
6881
- flatten = false;
6882
- }
6883
-
6884
- for ( i=0, ien=context.length ; i<ien ; i++ ) {
6885
- var apiInst = new _Api( context[i] );
6886
-
6887
- if ( type === 'table' ) {
6888
- ret = fn.call( apiInst, context[i], i );
6889
-
6890
- if ( ret !== undefined ) {
6891
- a.push( ret );
6892
- }
6893
- }
6894
- else if ( type === 'columns' || type === 'rows' ) {
6895
- // this has same length as context - one entry for each table
6896
- ret = fn.call( apiInst, context[i], this[i], i );
6897
-
6898
- if ( ret !== undefined ) {
6899
- a.push( ret );
6900
- }
6901
- }
6902
- else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
6903
- // columns and rows share the same structure.
6904
- // 'this' is an array of column indexes for each context
6905
- items = this[i];
6906
-
6907
- if ( type === 'column-rows' ) {
6908
- rows = _selector_row_indexes( context[i], selector.opts );
6909
- }
6910
-
6911
- for ( j=0, jen=items.length ; j<jen ; j++ ) {
6912
- item = items[j];
6913
-
6914
- if ( type === 'cell' ) {
6915
- ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
6916
- }
6917
- else {
6918
- ret = fn.call( apiInst, context[i], item, i, j, rows );
6919
- }
6920
-
6921
- if ( ret !== undefined ) {
6922
- a.push( ret );
6923
- }
6924
- }
6925
- }
6926
- }
6927
-
6928
- if ( a.length || alwaysNew ) {
6929
- var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
6930
- var apiSelector = api.selector;
6931
- apiSelector.rows = selector.rows;
6932
- apiSelector.cols = selector.cols;
6933
- apiSelector.opts = selector.opts;
6934
- return api;
6935
- }
6936
- return this;
6937
- },
6938
-
6939
-
6940
- lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
6941
- {
6942
- // Bit cheeky...
6943
- return this.indexOf.apply( this.toArray.reverse(), arguments );
6944
- },
6945
-
6946
-
6947
- length: 0,
6948
-
6949
-
6950
- map: function ( fn )
6951
- {
6952
- var a = [];
6953
-
6954
- if ( __arrayProto.map ) {
6955
- a = __arrayProto.map.call( this, fn, this );
6956
- }
6957
- else {
6958
- // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6959
- for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6960
- a.push( fn.call( this, this[i], i ) );
6961
- }
6962
- }
6963
-
6964
- return new _Api( this.context, a );
6965
- },
6966
-
6967
-
6968
- pluck: function ( prop )
6969
- {
6970
- return this.map( function ( el ) {
6971
- return el[ prop ];
6972
- } );
6973
- },
6974
-
6975
- pop: __arrayProto.pop,
6976
-
6977
-
6978
- push: __arrayProto.push,
6979
-
6980
-
6981
- // Does not return an API instance
6982
- reduce: __arrayProto.reduce || function ( fn, init )
6983
- {
6984
- return _fnReduce( this, fn, init, 0, this.length, 1 );
6985
- },
6986
-
6987
-
6988
- reduceRight: __arrayProto.reduceRight || function ( fn, init )
6989
- {
6990
- return _fnReduce( this, fn, init, this.length-1, -1, -1 );
6991
- },
6992
-
6993
-
6994
- reverse: __arrayProto.reverse,
6995
-
6996
-
6997
- // Object with rows, columns and opts
6998
- selector: null,
6999
-
7000
-
7001
- shift: __arrayProto.shift,
7002
-
7003
-
7004
- sort: __arrayProto.sort, // ? name - order?
7005
-
7006
-
7007
- splice: __arrayProto.splice,
7008
-
7009
-
7010
- toArray: function ()
7011
- {
7012
- return __arrayProto.slice.call( this );
7013
- },
7014
-
7015
-
7016
- to$: function ()
7017
- {
7018
- return $( this );
7019
- },
7020
-
7021
-
7022
- toJQuery: function ()
7023
- {
7024
- return $( this );
7025
- },
7026
-
7027
-
7028
- unique: function ()
7029
- {
7030
- return new _Api( this.context, _unique(this) );
7031
- },
7032
-
7033
-
7034
- unshift: __arrayProto.unshift
7035
- };
7036
-
7037
-
7038
- _Api.extend = function ( scope, obj, ext )
7039
- {
7040
- // Only extend API instances and static properties of the API
7041
- if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7042
- return;
7043
- }
7044
-
7045
- var
7046
- i, ien,
7047
- j, jen,
7048
- struct, inner,
7049
- methodScoping = function ( scope, fn, struc ) {
7050
- return function () {
7051
- var ret = fn.apply( scope, arguments );
7052
-
7053
- // Method extension
7054
- _Api.extend( ret, ret, struc.methodExt );
7055
- return ret;
7056
- };
7057
- };
7058
-
7059
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7060
- struct = ext[i];
7061
-
7062
- // Value
7063
- obj[ struct.name ] = typeof struct.val === 'function' ?
7064
- methodScoping( scope, struct.val, struct ) :
7065
- $.isPlainObject( struct.val ) ?
7066
- {} :
7067
- struct.val;
7068
-
7069
- obj[ struct.name ].__dt_wrapper = true;
7070
-
7071
- // Property extension
7072
- _Api.extend( scope, obj[ struct.name ], struct.propExt );
7073
- }
7074
- };
7075
-
7076
-
7077
- // @todo - Is there need for an augment function?
7078
- // _Api.augment = function ( inst, name )
7079
- // {
7080
- // // Find src object in the structure from the name
7081
- // var parts = name.split('.');
7082
-
7083
- // _Api.extend( inst, obj );
7084
- // };
7085
-
7086
-
7087
- // [
7088
- // {
7089
- // name: 'data' -- string - Property name
7090
- // val: function () {}, -- function - Api method (or undefined if just an object
7091
- // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
7092
- // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
7093
- // },
7094
- // {
7095
- // name: 'row'
7096
- // val: {},
7097
- // methodExt: [ ... ],
7098
- // propExt: [
7099
- // {
7100
- // name: 'data'
7101
- // val: function () {},
7102
- // methodExt: [ ... ],
7103
- // propExt: [ ... ]
7104
- // },
7105
- // ...
7106
- // ]
7107
- // }
7108
- // ]
7109
-
7110
- _Api.register = _api_register = function ( name, val )
7111
- {
7112
- if ( $.isArray( name ) ) {
7113
- for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7114
- _Api.register( name[j], val );
7115
- }
7116
- return;
7117
- }
7118
-
7119
- var
7120
- i, ien,
7121
- heir = name.split('.'),
7122
- struct = __apiStruct,
7123
- key, method;
7124
-
7125
- var find = function ( src, name ) {
7126
- for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7127
- if ( src[i].name === name ) {
7128
- return src[i];
7129
- }
7130
- }
7131
- return null;
7132
- };
7133
-
7134
- for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7135
- method = heir[i].indexOf('()') !== -1;
7136
- key = method ?
7137
- heir[i].replace('()', '') :
7138
- heir[i];
7139
-
7140
- var src = find( struct, key );
7141
- if ( ! src ) {
7142
- src = {
7143
- name: key,
7144
- val: {},
7145
- methodExt: [],
7146
- propExt: []
7147
- };
7148
- struct.push( src );
7149
- }
7150
-
7151
- if ( i === ien-1 ) {
7152
- src.val = val;
7153
- }
7154
- else {
7155
- struct = method ?
7156
- src.methodExt :
7157
- src.propExt;
7158
- }
7159
- }
7160
- };
7161
-
7162
-
7163
- _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7164
- _Api.register( pluralName, val );
7165
-
7166
- _Api.register( singularName, function () {
7167
- var ret = val.apply( this, arguments );
7168
-
7169
- if ( ret === this ) {
7170
- // Returned item is the API instance that was passed in, return it
7171
- return this;
7172
- }
7173
- else if ( ret instanceof _Api ) {
7174
- // New API instance returned, want the value from the first item
7175
- // in the returned array for the singular result.
7176
- return ret.length ?
7177
- $.isArray( ret[0] ) ?
7178
- new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7179
- ret[0] :
7180
- undefined;
7181
- }
7182
-
7183
- // Non-API return - just fire it back
7184
- return ret;
7185
- } );
7186
- };
7187
-
7188
-
7189
- /**
7190
- * Selector for HTML tables. Apply the given selector to the give array of
7191
- * DataTables settings objects.
7192
- *
7193
- * @param {string|integer} [selector] jQuery selector string or integer
7194
- * @param {array} Array of DataTables settings objects to be filtered
7195
- * @return {array}
7196
- * @ignore
7197
- */
7198
- var __table_selector = function ( selector, a )
7199
- {
7200
- // Integer is used to pick out a table by index
7201
- if ( typeof selector === 'number' ) {
7202
- return [ a[ selector ] ];
7203
- }
7204
-
7205
- // Perform a jQuery selector on the table nodes
7206
- var nodes = $.map( a, function (el, i) {
7207
- return el.nTable;
7208
- } );
7209
-
7210
- return $(nodes)
7211
- .filter( selector )
7212
- .map( function (i) {
7213
- // Need to translate back from the table node to the settings
7214
- var idx = $.inArray( this, nodes );
7215
- return a[ idx ];
7216
- } )
7217
- .toArray();
7218
- };
7219
-
7220
-
7221
-
7222
- /**
7223
- * Context selector for the API's context (i.e. the tables the API instance
7224
- * refers to.
7225
- *
7226
- * @name DataTable.Api#tables
7227
- * @param {string|integer} [selector] Selector to pick which tables the iterator
7228
- * should operate on. If not given, all tables in the current context are
7229
- * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7230
- * select multiple tables or as an integer to select a single table.
7231
- * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7232
- */
7233
- _api_register( 'tables()', function ( selector ) {
7234
- // A new instance is created if there was a selector specified
7235
- return selector ?
7236
- new _Api( __table_selector( selector, this.context ) ) :
7237
- this;
7238
- } );
7239
-
7240
-
7241
- _api_register( 'table()', function ( selector ) {
7242
- var tables = this.tables( selector );
7243
- var ctx = tables.context;
7244
-
7245
- // Truncate to the first matched table
7246
- return ctx.length ?
7247
- new _Api( ctx[0] ) :
7248
- tables;
7249
- } );
7250
-
7251
-
7252
- _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7253
- return this.iterator( 'table', function ( ctx ) {
7254
- return ctx.nTable;
7255
- }, 1 );
7256
- } );
7257
-
7258
-
7259
- _api_registerPlural( 'tables().body()', 'table().body()' , function () {
7260
- return this.iterator( 'table', function ( ctx ) {
7261
- return ctx.nTBody;
7262
- }, 1 );
7263
- } );
7264
-
7265
-
7266
- _api_registerPlural( 'tables().header()', 'table().header()' , function () {
7267
- return this.iterator( 'table', function ( ctx ) {
7268
- return ctx.nTHead;
7269
- }, 1 );
7270
- } );
7271
-
7272
-
7273
- _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7274
- return this.iterator( 'table', function ( ctx ) {
7275
- return ctx.nTFoot;
7276
- }, 1 );
7277
- } );
7278
-
7279
-
7280
- _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7281
- return this.iterator( 'table', function ( ctx ) {
7282
- return ctx.nTableWrapper;
7283
- }, 1 );
7284
- } );
7285
-
7286
-
7287
-
7288
- /**
7289
- * Redraw the tables in the current context.
7290
- */
7291
- _api_register( 'draw()', function ( paging ) {
7292
- return this.iterator( 'table', function ( settings ) {
7293
- if ( paging === 'page' ) {
7294
- _fnDraw( settings );
7295
- }
7296
- else {
7297
- if ( typeof paging === 'string' ) {
7298
- paging = paging === 'full-hold' ?
7299
- false :
7300
- true;
7301
- }
7302
-
7303
- _fnReDraw( settings, paging===false );
7304
- }
7305
- } );
7306
- } );
7307
-
7308
-
7309
-
7310
- /**
7311
- * Get the current page index.
7312
- *
7313
- * @return {integer} Current page index (zero based)
7314
- *//**
7315
- * Set the current page.
7316
- *
7317
- * Note that if you attempt to show a page which does not exist, DataTables will
7318
- * not throw an error, but rather reset the paging.
7319
- *
7320
- * @param {integer|string} action The paging action to take. This can be one of:
7321
- * * `integer` - The page index to jump to
7322
- * * `string` - An action to take:
7323
- * * `first` - Jump to first page.
7324
- * * `next` - Jump to the next page
7325
- * * `previous` - Jump to previous page
7326
- * * `last` - Jump to the last page.
7327
- * @returns {DataTables.Api} this
7328
- */
7329
- _api_register( 'page()', function ( action ) {
7330
- if ( action === undefined ) {
7331
- return this.page.info().page; // not an expensive call
7332
- }
7333
-
7334
- // else, have an action to take on all tables
7335
- return this.iterator( 'table', function ( settings ) {
7336
- _fnPageChange( settings, action );
7337
- } );
7338
- } );
7339
-
7340
-
7341
- /**
7342
- * Paging information for the first table in the current context.
7343
- *
7344
- * If you require paging information for another table, use the `table()` method
7345
- * with a suitable selector.
7346
- *
7347
- * @return {object} Object with the following properties set:
7348
- * * `page` - Current page index (zero based - i.e. the first page is `0`)
7349
- * * `pages` - Total number of pages
7350
- * * `start` - Display index for the first record shown on the current page
7351
- * * `end` - Display index for the last record shown on the current page
7352
- * * `length` - Display length (number of records). Note that generally `start
7353
- * + length = end`, but this is not always true, for example if there are
7354
- * only 2 records to show on the final page, with a length of 10.
7355
- * * `recordsTotal` - Full data set length
7356
- * * `recordsDisplay` - Data set length once the current filtering criterion
7357
- * are applied.
7358
- */
7359
- _api_register( 'page.info()', function ( action ) {
7360
- if ( this.context.length === 0 ) {
7361
- return undefined;
7362
- }
7363
-
7364
- var
7365
- settings = this.context[0],
7366
- start = settings._iDisplayStart,
7367
- len = settings._iDisplayLength,
7368
- visRecords = settings.fnRecordsDisplay(),
7369
- all = len === -1;
7370
-
7371
- return {
7372
- "page": all ? 0 : Math.floor( start / len ),
7373
- "pages": all ? 1 : Math.ceil( visRecords / len ),
7374
- "start": start,
7375
- "end": settings.fnDisplayEnd(),
7376
- "length": len,
7377
- "recordsTotal": settings.fnRecordsTotal(),
7378
- "recordsDisplay": visRecords,
7379
- "serverSide": _fnDataSource( settings ) === 'ssp'
7380
- };
7381
- } );
7382
-
7383
-
7384
- /**
7385
- * Get the current page length.
7386
- *
7387
- * @return {integer} Current page length. Note `-1` indicates that all records
7388
- * are to be shown.
7389
- *//**
7390
- * Set the current page length.
7391
- *
7392
- * @param {integer} Page length to set. Use `-1` to show all records.
7393
- * @returns {DataTables.Api} this
7394
- */
7395
- _api_register( 'page.len()', function ( len ) {
7396
- // Note that we can't call this function 'length()' because `length`
7397
- // is a Javascript property of functions which defines how many arguments
7398
- // the function expects.
7399
- if ( len === undefined ) {
7400
- return this.context.length !== 0 ?
7401
- this.context[0]._iDisplayLength :
7402
- undefined;
7403
- }
7404
-
7405
- // else, set the page length
7406
- return this.iterator( 'table', function ( settings ) {
7407
- _fnLengthChange( settings, len );
7408
- } );
7409
- } );
7410
-
7411
-
7412
-
7413
- var __reload = function ( settings, holdPosition, callback ) {
7414
- // Use the draw event to trigger a callback
7415
- if ( callback ) {
7416
- var api = new _Api( settings );
7417
-
7418
- api.one( 'draw', function () {
7419
- callback( api.ajax.json() );
7420
- } );
7421
- }
7422
-
7423
- if ( _fnDataSource( settings ) == 'ssp' ) {
7424
- _fnReDraw( settings, holdPosition );
7425
- }
7426
- else {
7427
- _fnProcessingDisplay( settings, true );
7428
-
7429
- // Cancel an existing request
7430
- var xhr = settings.jqXHR;
7431
- if ( xhr && xhr.readyState !== 4 ) {
7432
- xhr.abort();
7433
- }
7434
-
7435
- // Trigger xhr
7436
- _fnBuildAjax( settings, [], function( json ) {
7437
- _fnClearTable( settings );
7438
-
7439
- var data = _fnAjaxDataSrc( settings, json );
7440
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7441
- _fnAddData( settings, data[i] );
7442
- }
7443
-
7444
- _fnReDraw( settings, holdPosition );
7445
- _fnProcessingDisplay( settings, false );
7446
- } );
7447
- }
7448
- };
7449
-
7450
-
7451
- /**
7452
- * Get the JSON response from the last Ajax request that DataTables made to the
7453
- * server. Note that this returns the JSON from the first table in the current
7454
- * context.
7455
- *
7456
- * @return {object} JSON received from the server.
7457
- */
7458
- _api_register( 'ajax.json()', function () {
7459
- var ctx = this.context;
7460
-
7461
- if ( ctx.length > 0 ) {
7462
- return ctx[0].json;
7463
- }
7464
-
7465
- // else return undefined;
7466
- } );
7467
-
7468
-
7469
- /**
7470
- * Get the data submitted in the last Ajax request
7471
- */
7472
- _api_register( 'ajax.params()', function () {
7473
- var ctx = this.context;
7474
-
7475
- if ( ctx.length > 0 ) {
7476
- return ctx[0].oAjaxData;
7477
- }
7478
-
7479
- // else return undefined;
7480
- } );
7481
-
7482
-
7483
- /**
7484
- * Reload tables from the Ajax data source. Note that this function will
7485
- * automatically re-draw the table when the remote data has been loaded.
7486
- *
7487
- * @param {boolean} [reset=true] Reset (default) or hold the current paging
7488
- * position. A full re-sort and re-filter is performed when this method is
7489
- * called, which is why the pagination reset is the default action.
7490
- * @returns {DataTables.Api} this
7491
- */
7492
- _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7493
- return this.iterator( 'table', function (settings) {
7494
- __reload( settings, resetPaging===false, callback );
7495
- } );
7496
- } );
7497
-
7498
-
7499
- /**
7500
- * Get the current Ajax URL. Note that this returns the URL from the first
7501
- * table in the current context.
7502
- *
7503
- * @return {string} Current Ajax source URL
7504
- *//**
7505
- * Set the Ajax URL. Note that this will set the URL for all tables in the
7506
- * current context.
7507
- *
7508
- * @param {string} url URL to set.
7509
- * @returns {DataTables.Api} this
7510
- */
7511
- _api_register( 'ajax.url()', function ( url ) {
7512
- var ctx = this.context;
7513
-
7514
- if ( url === undefined ) {
7515
- // get
7516
- if ( ctx.length === 0 ) {
7517
- return undefined;
7518
- }
7519
- ctx = ctx[0];
7520
-
7521
- return ctx.ajax ?
7522
- $.isPlainObject( ctx.ajax ) ?
7523
- ctx.ajax.url :
7524
- ctx.ajax :
7525
- ctx.sAjaxSource;
7526
- }
7527
-
7528
- // set
7529
- return this.iterator( 'table', function ( settings ) {
7530
- if ( $.isPlainObject( settings.ajax ) ) {
7531
- settings.ajax.url = url;
7532
- }
7533
- else {
7534
- settings.ajax = url;
7535
- }
7536
- // No need to consider sAjaxSource here since DataTables gives priority
7537
- // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7538
- // value of `sAjaxSource` redundant.
7539
- } );
7540
- } );
7541
-
7542
-
7543
- /**
7544
- * Load data from the newly set Ajax URL. Note that this method is only
7545
- * available when `ajax.url()` is used to set a URL. Additionally, this method
7546
- * has the same effect as calling `ajax.reload()` but is provided for
7547
- * convenience when setting a new URL. Like `ajax.reload()` it will
7548
- * automatically redraw the table once the remote data has been loaded.
7549
- *
7550
- * @returns {DataTables.Api} this
7551
- */
7552
- _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7553
- // Same as a reload, but makes sense to present it for easy access after a
7554
- // url change
7555
- return this.iterator( 'table', function ( ctx ) {
7556
- __reload( ctx, resetPaging===false, callback );
7557
- } );
7558
- } );
7559
-
7560
-
7561
-
7562
-
7563
- var _selector_run = function ( type, selector, selectFn, settings, opts )
7564
- {
7565
- var
7566
- out = [], res,
7567
- a, i, ien, j, jen,
7568
- selectorType = typeof selector;
7569
-
7570
- // Can't just check for isArray here, as an API or jQuery instance might be
7571
- // given with their array like look
7572
- if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7573
- selector = [ selector ];
7574
- }
7575
-
7576
- for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7577
- a = selector[i] && selector[i].split ?
7578
- selector[i].split(',') :
7579
- [ selector[i] ];
7580
-
7581
- for ( j=0, jen=a.length ; j<jen ; j++ ) {
7582
- res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7583
-
7584
- if ( res && res.length ) {
7585
- out.push.apply( out, res );
7586
- }
7587
- }
7588
- }
7589
-
7590
- // selector extensions
7591
- var ext = _ext.selector[ type ];
7592
- if ( ext.length ) {
7593
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7594
- out = ext[i]( settings, opts, out );
7595
- }
7596
- }
7597
-
7598
- return out;
7599
- };
7600
-
7601
-
7602
- var _selector_opts = function ( opts )
7603
- {
7604
- if ( ! opts ) {
7605
- opts = {};
7606
- }
7607
-
7608
- // Backwards compatibility for 1.9- which used the terminology filter rather
7609
- // than search
7610
- if ( opts.filter && opts.search === undefined ) {
7611
- opts.search = opts.filter;
7612
- }
7613
-
7614
- return $.extend( {
7615
- search: 'none',
7616
- order: 'current',
7617
- page: 'all'
7618
- }, opts );
7619
- };
7620
-
7621
-
7622
- var _selector_first = function ( inst )
7623
- {
7624
- // Reduce the API instance to the first item found
7625
- for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7626
- if ( inst[i].length > 0 ) {
7627
- // Assign the first element to the first item in the instance
7628
- // and truncate the instance and context
7629
- inst[0] = inst[i];
7630
- inst[0].length = 1;
7631
- inst.length = 1;
7632
- inst.context = [ inst.context[i] ];
7633
-
7634
- return inst;
7635
- }
7636
- }
7637
-
7638
- // Not found - return an empty instance
7639
- inst.length = 0;
7640
- return inst;
7641
- };
7642
-
7643
-
7644
- var _selector_row_indexes = function ( settings, opts )
7645
- {
7646
- var
7647
- i, ien, tmp, a=[],
7648
- displayFiltered = settings.aiDisplay,
7649
- displayMaster = settings.aiDisplayMaster;
7650
-
7651
- var
7652
- search = opts.search, // none, applied, removed
7653
- order = opts.order, // applied, current, index (original - compatibility with 1.9)
7654
- page = opts.page; // all, current
7655
-
7656
- if ( _fnDataSource( settings ) == 'ssp' ) {
7657
- // In server-side processing mode, most options are irrelevant since
7658
- // rows not shown don't exist and the index order is the applied order
7659
- // Removed is a special case - for consistency just return an empty
7660
- // array
7661
- return search === 'removed' ?
7662
- [] :
7663
- _range( 0, displayMaster.length );
7664
- }
7665
- else if ( page == 'current' ) {
7666
- // Current page implies that order=current and fitler=applied, since it is
7667
- // fairly senseless otherwise, regardless of what order and search actually
7668
- // are
7669
- for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7670
- a.push( displayFiltered[i] );
7671
- }
7672
- }
7673
- else if ( order == 'current' || order == 'applied' ) {
7674
- a = search == 'none' ?
7675
- displayMaster.slice() : // no search
7676
- search == 'applied' ?
7677
- displayFiltered.slice() : // applied search
7678
- $.map( displayMaster, function (el, i) { // removed search
7679
- return $.inArray( el, displayFiltered ) === -1 ? el : null;
7680
- } );
7681
- }
7682
- else if ( order == 'index' || order == 'original' ) {
7683
- for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7684
- if ( search == 'none' ) {
7685
- a.push( i );
7686
- }
7687
- else { // applied | removed
7688
- tmp = $.inArray( i, displayFiltered );
7689
-
7690
- if ((tmp === -1 && search == 'removed') ||
7691
- (tmp >= 0 && search == 'applied') )
7692
- {
7693
- a.push( i );
7694
- }
7695
- }
7696
- }
7697
- }
7698
-
7699
- return a;
7700
- };
7701
-
7702
-
7703
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7704
- * Rows
7705
- *
7706
- * {} - no selector - use all available rows
7707
- * {integer} - row aoData index
7708
- * {node} - TR node
7709
- * {string} - jQuery selector to apply to the TR elements
7710
- * {array} - jQuery array of nodes, or simply an array of TR nodes
7711
- *
7712
- */
7713
-
7714
-
7715
- var __row_selector = function ( settings, selector, opts )
7716
- {
7717
- var run = function ( sel ) {
7718
- var selInt = _intVal( sel );
7719
- var i, ien;
7720
-
7721
- // Short cut - selector is a number and no options provided (default is
7722
- // all records, so no need to check if the index is in there, since it
7723
- // must be - dev error if the index doesn't exist).
7724
- if ( selInt !== null && ! opts ) {
7725
- return [ selInt ];
7726
- }
7727
-
7728
- var rows = _selector_row_indexes( settings, opts );
7729
-
7730
- if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7731
- // Selector - integer
7732
- return [ selInt ];
7733
- }
7734
- else if ( ! sel ) {
7735
- // Selector - none
7736
- return rows;
7737
- }
7738
-
7739
- // Selector - function
7740
- if ( typeof sel === 'function' ) {
7741
- return $.map( rows, function (idx) {
7742
- var row = settings.aoData[ idx ];
7743
- return sel( idx, row._aData, row.nTr ) ? idx : null;
7744
- } );
7745
- }
7746
-
7747
- // Get nodes in the order from the `rows` array with null values removed
7748
- var nodes = _removeEmpty(
7749
- _pluck_order( settings.aoData, rows, 'nTr' )
7750
- );
7751
-
7752
- // Selector - node
7753
- if ( sel.nodeName ) {
7754
- if ( $.inArray( sel, nodes ) !== -1 ) {
7755
- return [ sel._DT_RowIndex ]; // sel is a TR node that is in the table
7756
- // and DataTables adds a prop for fast lookup
7757
- }
7758
- }
7759
-
7760
- // ID selector. Want to always be able to select rows by id, regardless
7761
- // of if the tr element has been created or not, so can't rely upon
7762
- // jQuery here - hence a custom implementation. This does not match
7763
- // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7764
- // but to select it using a CSS selector engine (like Sizzle or
7765
- // querySelect) it would need to need to be escaped for some characters.
7766
- // DataTables simplifies this for row selectors since you can select
7767
- // only a row. A # indicates an id any anything that follows is the id -
7768
- // unescaped.
7769
- if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7770
- // get row index from id
7771
- var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7772
- if ( rowObj !== undefined ) {
7773
- return [ rowObj.idx ];
7774
- }
7775
-
7776
- // need to fall through to jQuery in case there is DOM id that
7777
- // matches
7778
- }
7779
-
7780
- // Selector - jQuery selector string, array of nodes or jQuery object/
7781
- // As jQuery's .filter() allows jQuery objects to be passed in filter,
7782
- // it also allows arrays, so this will cope with all three options
7783
- return $(nodes)
7784
- .filter( sel )
7785
- .map( function () {
7786
- return this._DT_RowIndex;
7787
- } )
7788
- .toArray();
7789
- };
7790
-
7791
- return _selector_run( 'row', selector, run, settings, opts );
7792
- };
7793
-
7794
-
7795
- _api_register( 'rows()', function ( selector, opts ) {
7796
- // argument shifting
7797
- if ( selector === undefined ) {
7798
- selector = '';
7799
- }
7800
- else if ( $.isPlainObject( selector ) ) {
7801
- opts = selector;
7802
- selector = '';
7803
- }
7804
-
7805
- opts = _selector_opts( opts );
7806
-
7807
- var inst = this.iterator( 'table', function ( settings ) {
7808
- return __row_selector( settings, selector, opts );
7809
- }, 1 );
7810
-
7811
- // Want argument shifting here and in __row_selector?
7812
- inst.selector.rows = selector;
7813
- inst.selector.opts = opts;
7814
-
7815
- return inst;
7816
- } );
7817
-
7818
- _api_register( 'rows().nodes()', function () {
7819
- return this.iterator( 'row', function ( settings, row ) {
7820
- return settings.aoData[ row ].nTr || undefined;
7821
- }, 1 );
7822
- } );
7823
-
7824
- _api_register( 'rows().data()', function () {
7825
- return this.iterator( true, 'rows', function ( settings, rows ) {
7826
- return _pluck_order( settings.aoData, rows, '_aData' );
7827
- }, 1 );
7828
- } );
7829
-
7830
- _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
7831
- return this.iterator( 'row', function ( settings, row ) {
7832
- var r = settings.aoData[ row ];
7833
- return type === 'search' ? r._aFilterData : r._aSortData;
7834
- }, 1 );
7835
- } );
7836
-
7837
- _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
7838
- return this.iterator( 'row', function ( settings, row ) {
7839
- _fnInvalidate( settings, row, src );
7840
- } );
7841
- } );
7842
-
7843
- _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
7844
- return this.iterator( 'row', function ( settings, row ) {
7845
- return row;
7846
- }, 1 );
7847
- } );
7848
-
7849
- _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
7850
- var a = [];
7851
- var context = this.context;
7852
-
7853
- // `iterator` will drop undefined values, but in this case we want them
7854
- for ( var i=0, ien=context.length ; i<ien ; i++ ) {
7855
- for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
7856
- var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
7857
- a.push( (hash === true ? '#' : '' )+ id );
7858
- }
7859
- }
7860
-
7861
- return new _Api( context, a );
7862
- } );
7863
-
7864
- _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7865
- var that = this;
7866
-
7867
- this.iterator( 'row', function ( settings, row, thatIdx ) {
7868
- var data = settings.aoData;
7869
-
7870
- data.splice( row, 1 );
7871
-
7872
- // Update the _DT_RowIndex parameter on all rows in the table
7873
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7874
- if ( data[i].nTr !== null ) {
7875
- data[i].nTr._DT_RowIndex = i;
7876
- }
7877
- }
7878
-
7879
- // Delete from the display arrays
7880
- _fnDeleteIndex( settings.aiDisplayMaster, row );
7881
- _fnDeleteIndex( settings.aiDisplay, row );
7882
- _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
7883
-
7884
- // Check for an 'overflow' they case for displaying the table
7885
- _fnLengthOverflow( settings );
7886
- } );
7887
-
7888
- this.iterator( 'table', function ( settings ) {
7889
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7890
- settings.aoData[i].idx = i;
7891
- }
7892
- } );
7893
-
7894
- return this;
7895
- } );
7896
-
7897
-
7898
- _api_register( 'rows.add()', function ( rows ) {
7899
- var newRows = this.iterator( 'table', function ( settings ) {
7900
- var row, i, ien;
7901
- var out = [];
7902
-
7903
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
7904
- row = rows[i];
7905
-
7906
- if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7907
- out.push( _fnAddTr( settings, row )[0] );
7908
- }
7909
- else {
7910
- out.push( _fnAddData( settings, row ) );
7911
- }
7912
- }
7913
-
7914
- return out;
7915
- }, 1 );
7916
-
7917
- // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7918
- var modRows = this.rows( -1 );
7919
- modRows.pop();
7920
- modRows.push.apply( modRows, newRows.toArray() );
7921
-
7922
- return modRows;
7923
- } );
7924
-
7925
-
7926
-
7927
-
7928
-
7929
- /**
7930
- *
7931
- */
7932
- _api_register( 'row()', function ( selector, opts ) {
7933
- return _selector_first( this.rows( selector, opts ) );
7934
- } );
7935
-
7936
-
7937
- _api_register( 'row().data()', function ( data ) {
7938
- var ctx = this.context;
7939
-
7940
- if ( data === undefined ) {
7941
- // Get
7942
- return ctx.length && this.length ?
7943
- ctx[0].aoData[ this[0] ]._aData :
7944
- undefined;
7945
- }
7946
-
7947
- // Set
7948
- ctx[0].aoData[ this[0] ]._aData = data;
7949
-
7950
- // Automatically invalidate
7951
- _fnInvalidate( ctx[0], this[0], 'data' );
7952
-
7953
- return this;
7954
- } );
7955
-
7956
-
7957
- _api_register( 'row().node()', function () {
7958
- var ctx = this.context;
7959
-
7960
- return ctx.length && this.length ?
7961
- ctx[0].aoData[ this[0] ].nTr || null :
7962
- null;
7963
- } );
7964
-
7965
-
7966
- _api_register( 'row.add()', function ( row ) {
7967
- // Allow a jQuery object to be passed in - only a single row is added from
7968
- // it though - the first element in the set
7969
- if ( row instanceof $ && row.length ) {
7970
- row = row[0];
7971
- }
7972
-
7973
- var rows = this.iterator( 'table', function ( settings ) {
7974
- if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7975
- return _fnAddTr( settings, row )[0];
7976
- }
7977
- return _fnAddData( settings, row );
7978
- } );
7979
-
7980
- // Return an Api.rows() extended instance, with the newly added row selected
7981
- return this.row( rows[0] );
7982
- } );
7983
-
7984
-
7985
-
7986
- var __details_add = function ( ctx, row, data, klass )
7987
- {
7988
- // Convert to array of TR elements
7989
- var rows = [];
7990
- var addRow = function ( r, k ) {
7991
- // Recursion to allow for arrays of jQuery objects
7992
- if ( $.isArray( r ) || r instanceof $ ) {
7993
- for ( var i=0, ien=r.length ; i<ien ; i++ ) {
7994
- addRow( r[i], k );
7995
- }
7996
- return;
7997
- }
7998
-
7999
- // If we get a TR element, then just add it directly - up to the dev
8000
- // to add the correct number of columns etc
8001
- if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
8002
- rows.push( r );
8003
- }
8004
- else {
8005
- // Otherwise create a row with a wrapper
8006
- var created = $('<tr><td/></tr>').addClass( k );
8007
- $('td', created)
8008
- .addClass( k )
8009
- .html( r )
8010
- [0].colSpan = _fnVisbleColumns( ctx );
8011
-
8012
- rows.push( created[0] );
8013
- }
8014
- };
8015
-
8016
- addRow( data, klass );
8017
-
8018
- if ( row._details ) {
8019
- row._details.remove();
8020
- }
8021
-
8022
- row._details = $(rows);
8023
-
8024
- // If the children were already shown, that state should be retained
8025
- if ( row._detailsShow ) {
8026
- row._details.insertAfter( row.nTr );
8027
- }
8028
- };
8029
-
8030
-
8031
- var __details_remove = function ( api, idx )
8032
- {
8033
- var ctx = api.context;
8034
-
8035
- if ( ctx.length ) {
8036
- var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8037
-
8038
- if ( row && row._details ) {
8039
- row._details.remove();
8040
-
8041
- row._detailsShow = undefined;
8042
- row._details = undefined;
8043
- }
8044
- }
8045
- };
8046
-
8047
-
8048
- var __details_display = function ( api, show ) {
8049
- var ctx = api.context;
8050
-
8051
- if ( ctx.length && api.length ) {
8052
- var row = ctx[0].aoData[ api[0] ];
8053
-
8054
- if ( row._details ) {
8055
- row._detailsShow = show;
8056
-
8057
- if ( show ) {
8058
- row._details.insertAfter( row.nTr );
8059
- }
8060
- else {
8061
- row._details.detach();
8062
- }
8063
-
8064
- __details_events( ctx[0] );
8065
- }
8066
- }
8067
- };
8068
-
8069
-
8070
- var __details_events = function ( settings )
8071
- {
8072
- var api = new _Api( settings );
8073
- var namespace = '.dt.DT_details';
8074
- var drawEvent = 'draw'+namespace;
8075
- var colvisEvent = 'column-visibility'+namespace;
8076
- var destroyEvent = 'destroy'+namespace;
8077
- var data = settings.aoData;
8078
-
8079
- api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8080
-
8081
- if ( _pluck( data, '_details' ).length > 0 ) {
8082
- // On each draw, insert the required elements into the document
8083
- api.on( drawEvent, function ( e, ctx ) {
8084
- if ( settings !== ctx ) {
8085
- return;
8086
- }
8087
-
8088
- api.rows( {page:'current'} ).eq(0).each( function (idx) {
8089
- // Internal data grab
8090
- var row = data[ idx ];
8091
-
8092
- if ( row._detailsShow ) {
8093
- row._details.insertAfter( row.nTr );
8094
- }
8095
- } );
8096
- } );
8097
-
8098
- // Column visibility change - update the colspan
8099
- api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8100
- if ( settings !== ctx ) {
8101
- return;
8102
- }
8103
-
8104
- // Update the colspan for the details rows (note, only if it already has
8105
- // a colspan)
8106
- var row, visible = _fnVisbleColumns( ctx );
8107
-
8108
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8109
- row = data[i];
8110
-
8111
- if ( row._details ) {
8112
- row._details.children('td[colspan]').attr('colspan', visible );
8113
- }
8114
- }
8115
- } );
8116
-
8117
- // Table destroyed - nuke any child rows
8118
- api.on( destroyEvent, function ( e, ctx ) {
8119
- if ( settings !== ctx ) {
8120
- return;
8121
- }
8122
-
8123
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8124
- if ( data[i]._details ) {
8125
- __details_remove( api, i );
8126
- }
8127
- }
8128
- } );
8129
- }
8130
- };
8131
-
8132
- // Strings for the method names to help minification
8133
- var _emp = '';
8134
- var _child_obj = _emp+'row().child';
8135
- var _child_mth = _child_obj+'()';
8136
-
8137
- // data can be:
8138
- // tr
8139
- // string
8140
- // jQuery or array of any of the above
8141
- _api_register( _child_mth, function ( data, klass ) {
8142
- var ctx = this.context;
8143
-
8144
- if ( data === undefined ) {
8145
- // get
8146
- return ctx.length && this.length ?
8147
- ctx[0].aoData[ this[0] ]._details :
8148
- undefined;
8149
- }
8150
- else if ( data === true ) {
8151
- // show
8152
- this.child.show();
8153
- }
8154
- else if ( data === false ) {
8155
- // remove
8156
- __details_remove( this );
8157
- }
8158
- else if ( ctx.length && this.length ) {
8159
- // set
8160
- __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8161
- }
8162
-
8163
- return this;
8164
- } );
8165
-
8166
-
8167
- _api_register( [
8168
- _child_obj+'.show()',
8169
- _child_mth+'.show()' // only when `child()` was called with parameters (without
8170
- ], function ( show ) { // it returns an object and this method is not executed)
8171
- __details_display( this, true );
8172
- return this;
8173
- } );
8174
-
8175
-
8176
- _api_register( [
8177
- _child_obj+'.hide()',
8178
- _child_mth+'.hide()' // only when `child()` was called with parameters (without
8179
- ], function () { // it returns an object and this method is not executed)
8180
- __details_display( this, false );
8181
- return this;
8182
- } );
8183
-
8184
-
8185
- _api_register( [
8186
- _child_obj+'.remove()',
8187
- _child_mth+'.remove()' // only when `child()` was called with parameters (without
8188
- ], function () { // it returns an object and this method is not executed)
8189
- __details_remove( this );
8190
- return this;
8191
- } );
8192
-
8193
-
8194
- _api_register( _child_obj+'.isShown()', function () {
8195
- var ctx = this.context;
8196
-
8197
- if ( ctx.length && this.length ) {
8198
- // _detailsShown as false or undefined will fall through to return false
8199
- return ctx[0].aoData[ this[0] ]._detailsShow || false;
8200
- }
8201
- return false;
8202
- } );
8203
-
8204
-
8205
-
8206
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8207
- * Columns
8208
- *
8209
- * {integer} - column index (>=0 count from left, <0 count from right)
8210
- * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
8211
- * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
8212
- * "{string}:name" - column name
8213
- * "{string}" - jQuery selector on column header nodes
8214
- *
8215
- */
8216
-
8217
- // can be an array of these items, comma separated list, or an array of comma
8218
- // separated lists
8219
-
8220
- var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
8221
-
8222
-
8223
- // r1 and r2 are redundant - but it means that the parameters match for the
8224
- // iterator callback in columns().data()
8225
- var __columnData = function ( settings, column, r1, r2, rows ) {
8226
- var a = [];
8227
- for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8228
- a.push( _fnGetCellData( settings, rows[row], column ) );
8229
- }
8230
- return a;
8231
- };
8232
-
8233
-
8234
- var __column_selector = function ( settings, selector, opts )
8235
- {
8236
- var
8237
- columns = settings.aoColumns,
8238
- names = _pluck( columns, 'sName' ),
8239
- nodes = _pluck( columns, 'nTh' );
8240
-
8241
- var run = function ( s ) {
8242
- var selInt = _intVal( s );
8243
-
8244
- // Selector - all
8245
- if ( s === '' ) {
8246
- return _range( columns.length );
8247
- }
8248
-
8249
- // Selector - index
8250
- if ( selInt !== null ) {
8251
- return [ selInt >= 0 ?
8252
- selInt : // Count from left
8253
- columns.length + selInt // Count from right (+ because its a negative value)
8254
- ];
8255
- }
8256
-
8257
- // Selector = function
8258
- if ( typeof s === 'function' ) {
8259
- var rows = _selector_row_indexes( settings, opts );
8260
-
8261
- return $.map( columns, function (col, idx) {
8262
- return s(
8263
- idx,
8264
- __columnData( settings, idx, 0, 0, rows ),
8265
- nodes[ idx ]
8266
- ) ? idx : null;
8267
- } );
8268
- }
8269
-
8270
- // jQuery or string selector
8271
- var match = typeof s === 'string' ?
8272
- s.match( __re_column_selector ) :
8273
- '';
8274
-
8275
- if ( match ) {
8276
- switch( match[2] ) {
8277
- case 'visIdx':
8278
- case 'visible':
8279
- var idx = parseInt( match[1], 10 );
8280
- // Visible index given, convert to column index
8281
- if ( idx < 0 ) {
8282
- // Counting from the right
8283
- var visColumns = $.map( columns, function (col,i) {
8284
- return col.bVisible ? i : null;
8285
- } );
8286
- return [ visColumns[ visColumns.length + idx ] ];
8287
- }
8288
- // Counting from the left
8289
- return [ _fnVisibleToColumnIndex( settings, idx ) ];
8290
-
8291
- case 'name':
8292
- // match by name. `names` is column index complete and in order
8293
- return $.map( names, function (name, i) {
8294
- return name === match[1] ? i : null;
8295
- } );
8296
- }
8297
- }
8298
- else {
8299
- // jQuery selector on the TH elements for the columns
8300
- return $( nodes )
8301
- .filter( s )
8302
- .map( function () {
8303
- return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8304
- } )
8305
- .toArray();
8306
- }
8307
- };
8308
-
8309
- return _selector_run( 'column', selector, run, settings, opts );
8310
- };
8311
-
8312
-
8313
- var __setColumnVis = function ( settings, column, vis, recalc ) {
8314
- var
8315
- cols = settings.aoColumns,
8316
- col = cols[ column ],
8317
- data = settings.aoData,
8318
- row, cells, i, ien, tr;
8319
-
8320
- // Get
8321
- if ( vis === undefined ) {
8322
- return col.bVisible;
8323
- }
8324
-
8325
- // Set
8326
- // No change
8327
- if ( col.bVisible === vis ) {
8328
- return;
8329
- }
8330
-
8331
- if ( vis ) {
8332
- // Insert column
8333
- // Need to decide if we should use appendChild or insertBefore
8334
- var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8335
-
8336
- for ( i=0, ien=data.length ; i<ien ; i++ ) {
8337
- tr = data[i].nTr;
8338
- cells = data[i].anCells;
8339
-
8340
- if ( tr ) {
8341
- // insertBefore can act like appendChild if 2nd arg is null
8342
- tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8343
- }
8344
- }
8345
- }
8346
- else {
8347
- // Remove column
8348
- $( _pluck( settings.aoData, 'anCells', column ) ).detach();
8349
- }
8350
-
8351
- // Common actions
8352
- col.bVisible = vis;
8353
- _fnDrawHead( settings, settings.aoHeader );
8354
- _fnDrawHead( settings, settings.aoFooter );
8355
-
8356
- if ( recalc === undefined || recalc ) {
8357
- // Automatically adjust column sizing
8358
- _fnAdjustColumnSizing( settings );
8359
-
8360
- // Realign columns for scrolling
8361
- if ( settings.oScroll.sX || settings.oScroll.sY ) {
8362
- _fnScrollDraw( settings );
8363
- }
8364
- }
8365
-
8366
- _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
8367
-
8368
- _fnSaveState( settings );
8369
- };
8370
-
8371
-
8372
- _api_register( 'columns()', function ( selector, opts ) {
8373
- // argument shifting
8374
- if ( selector === undefined ) {
8375
- selector = '';
8376
- }
8377
- else if ( $.isPlainObject( selector ) ) {
8378
- opts = selector;
8379
- selector = '';
8380
- }
8381
-
8382
- opts = _selector_opts( opts );
8383
-
8384
- var inst = this.iterator( 'table', function ( settings ) {
8385
- return __column_selector( settings, selector, opts );
8386
- }, 1 );
8387
-
8388
- // Want argument shifting here and in _row_selector?
8389
- inst.selector.cols = selector;
8390
- inst.selector.opts = opts;
8391
-
8392
- return inst;
8393
- } );
8394
-
8395
- _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8396
- return this.iterator( 'column', function ( settings, column ) {
8397
- return settings.aoColumns[column].nTh;
8398
- }, 1 );
8399
- } );
8400
-
8401
- _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8402
- return this.iterator( 'column', function ( settings, column ) {
8403
- return settings.aoColumns[column].nTf;
8404
- }, 1 );
8405
- } );
8406
-
8407
- _api_registerPlural( 'columns().data()', 'column().data()', function () {
8408
- return this.iterator( 'column-rows', __columnData, 1 );
8409
- } );
8410
-
8411
- _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8412
- return this.iterator( 'column', function ( settings, column ) {
8413
- return settings.aoColumns[column].mData;
8414
- }, 1 );
8415
- } );
8416
-
8417
- _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8418
- return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8419
- return _pluck_order( settings.aoData, rows,
8420
- type === 'search' ? '_aFilterData' : '_aSortData', column
8421
- );
8422
- }, 1 );
8423
- } );
8424
-
8425
- _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8426
- return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8427
- return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8428
- }, 1 );
8429
- } );
8430
-
8431
- _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8432
- return this.iterator( 'column', function ( settings, column ) {
8433
- if ( vis === undefined ) {
8434
- return settings.aoColumns[ column ].bVisible;
8435
- } // else
8436
- __setColumnVis( settings, column, vis, calc );
8437
- } );
8438
- } );
8439
-
8440
- _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8441
- return this.iterator( 'column', function ( settings, column ) {
8442
- return type === 'visible' ?
8443
- _fnColumnIndexToVisible( settings, column ) :
8444
- column;
8445
- }, 1 );
8446
- } );
8447
-
8448
- _api_register( 'columns.adjust()', function () {
8449
- return this.iterator( 'table', function ( settings ) {
8450
- _fnAdjustColumnSizing( settings );
8451
- }, 1 );
8452
- } );
8453
-
8454
- _api_register( 'column.index()', function ( type, idx ) {
8455
- if ( this.context.length !== 0 ) {
8456
- var ctx = this.context[0];
8457
-
8458
- if ( type === 'fromVisible' || type === 'toData' ) {
8459
- return _fnVisibleToColumnIndex( ctx, idx );
8460
- }
8461
- else if ( type === 'fromData' || type === 'toVisible' ) {
8462
- return _fnColumnIndexToVisible( ctx, idx );
8463
- }
8464
- }
8465
- } );
8466
-
8467
- _api_register( 'column()', function ( selector, opts ) {
8468
- return _selector_first( this.columns( selector, opts ) );
8469
- } );
8470
-
8471
-
8472
-
8473
-
8474
- var __cell_selector = function ( settings, selector, opts )
8475
- {
8476
- var data = settings.aoData;
8477
- var rows = _selector_row_indexes( settings, opts );
8478
- var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8479
- var allCells = $( [].concat.apply([], cells) );
8480
- var row;
8481
- var columns = settings.aoColumns.length;
8482
- var a, i, ien, j, o, host;
8483
-
8484
- var run = function ( s ) {
8485
- var fnSelector = typeof s === 'function';
8486
-
8487
- if ( s === null || s === undefined || fnSelector ) {
8488
- // All cells and function selectors
8489
- a = [];
8490
-
8491
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8492
- row = rows[i];
8493
-
8494
- for ( j=0 ; j<columns ; j++ ) {
8495
- o = {
8496
- row: row,
8497
- column: j
8498
- };
8499
-
8500
- if ( fnSelector ) {
8501
- // Selector - function
8502
- host = settings.aoData[ row ];
8503
-
8504
- if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8505
- a.push( o );
8506
- }
8507
- }
8508
- else {
8509
- // Selector - all
8510
- a.push( o );
8511
- }
8512
- }
8513
- }
8514
-
8515
- return a;
8516
- }
8517
-
8518
- // Selector - index
8519
- if ( $.isPlainObject( s ) ) {
8520
- return [s];
8521
- }
8522
-
8523
- // Selector - jQuery filtered cells
8524
- return allCells
8525
- .filter( s )
8526
- .map( function (i, el) {
8527
- row = el.parentNode._DT_RowIndex;
8528
-
8529
- return {
8530
- row: row,
8531
- column: $.inArray( el, data[ row ].anCells )
8532
- };
8533
- } )
8534
- .toArray();
8535
- };
8536
-
8537
- return _selector_run( 'cell', selector, run, settings, opts );
8538
- };
8539
-
8540
-
8541
-
8542
-
8543
- _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8544
- // Argument shifting
8545
- if ( $.isPlainObject( rowSelector ) ) {
8546
- // Indexes
8547
- if ( rowSelector.row === undefined ) {
8548
- // Selector options in first parameter
8549
- opts = rowSelector;
8550
- rowSelector = null;
8551
- }
8552
- else {
8553
- // Cell index objects in first parameter
8554
- opts = columnSelector;
8555
- columnSelector = null;
8556
- }
8557
- }
8558
- if ( $.isPlainObject( columnSelector ) ) {
8559
- opts = columnSelector;
8560
- columnSelector = null;
8561
- }
8562
-
8563
- // Cell selector
8564
- if ( columnSelector === null || columnSelector === undefined ) {
8565
- return this.iterator( 'table', function ( settings ) {
8566
- return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8567
- } );
8568
- }
8569
-
8570
- // Row + column selector
8571
- var columns = this.columns( columnSelector, opts );
8572
- var rows = this.rows( rowSelector, opts );
8573
- var a, i, ien, j, jen;
8574
-
8575
- var cells = this.iterator( 'table', function ( settings, idx ) {
8576
- a = [];
8577
-
8578
- for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8579
- for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8580
- a.push( {
8581
- row: rows[idx][i],
8582
- column: columns[idx][j]
8583
- } );
8584
- }
8585
- }
8586
-
8587
- return a;
8588
- }, 1 );
8589
-
8590
- $.extend( cells.selector, {
8591
- cols: columnSelector,
8592
- rows: rowSelector,
8593
- opts: opts
8594
- } );
8595
-
8596
- return cells;
8597
- } );
8598
-
8599
-
8600
- _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8601
- return this.iterator( 'cell', function ( settings, row, column ) {
8602
- var cells = settings.aoData[ row ].anCells;
8603
- return cells ?
8604
- cells[ column ] :
8605
- undefined;
8606
- }, 1 );
8607
- } );
8608
-
8609
-
8610
- _api_register( 'cells().data()', function () {
8611
- return this.iterator( 'cell', function ( settings, row, column ) {
8612
- return _fnGetCellData( settings, row, column );
8613
- }, 1 );
8614
- } );
8615
-
8616
-
8617
- _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8618
- type = type === 'search' ? '_aFilterData' : '_aSortData';
8619
-
8620
- return this.iterator( 'cell', function ( settings, row, column ) {
8621
- return settings.aoData[ row ][ type ][ column ];
8622
- }, 1 );
8623
- } );
8624
-
8625
-
8626
- _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8627
- return this.iterator( 'cell', function ( settings, row, column ) {
8628
- return _fnGetCellData( settings, row, column, type );
8629
- }, 1 );
8630
- } );
8631
-
8632
-
8633
- _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8634
- return this.iterator( 'cell', function ( settings, row, column ) {
8635
- return {
8636
- row: row,
8637
- column: column,
8638
- columnVisible: _fnColumnIndexToVisible( settings, column )
8639
- };
8640
- }, 1 );
8641
- } );
8642
-
8643
-
8644
- _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8645
- return this.iterator( 'cell', function ( settings, row, column ) {
8646
- _fnInvalidate( settings, row, src, column );
8647
- } );
8648
- } );
8649
-
8650
-
8651
-
8652
- _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8653
- return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8654
- } );
8655
-
8656
-
8657
- _api_register( 'cell().data()', function ( data ) {
8658
- var ctx = this.context;
8659
- var cell = this[0];
8660
-
8661
- if ( data === undefined ) {
8662
- // Get
8663
- return ctx.length && cell.length ?
8664
- _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8665
- undefined;
8666
- }
8667
-
8668
- // Set
8669
- _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8670
- _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8671
-
8672
- return this;
8673
- } );
8674
-
8675
-
8676
-
8677
- /**
8678
- * Get current ordering (sorting) that has been applied to the table.
8679
- *
8680
- * @returns {array} 2D array containing the sorting information for the first
8681
- * table in the current context. Each element in the parent array represents
8682
- * a column being sorted upon (i.e. multi-sorting with two columns would have
8683
- * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8684
- * the column index that the sorting condition applies to, the second is the
8685
- * direction of the sort (`desc` or `asc`) and, optionally, the third is the
8686
- * index of the sorting order from the `column.sorting` initialisation array.
8687
- *//**
8688
- * Set the ordering for the table.
8689
- *
8690
- * @param {integer} order Column index to sort upon.
8691
- * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8692
- * @returns {DataTables.Api} this
8693
- *//**
8694
- * Set the ordering for the table.
8695
- *
8696
- * @param {array} order 1D array of sorting information to be applied.
8697
- * @param {array} [...] Optional additional sorting conditions
8698
- * @returns {DataTables.Api} this
8699
- *//**
8700
- * Set the ordering for the table.
8701
- *
8702
- * @param {array} order 2D array of sorting information to be applied.
8703
- * @returns {DataTables.Api} this
8704
- */
8705
- _api_register( 'order()', function ( order, dir ) {
8706
- var ctx = this.context;
8707
-
8708
- if ( order === undefined ) {
8709
- // get
8710
- return ctx.length !== 0 ?
8711
- ctx[0].aaSorting :
8712
- undefined;
8713
- }
8714
-
8715
- // set
8716
- if ( typeof order === 'number' ) {
8717
- // Simple column / direction passed in
8718
- order = [ [ order, dir ] ];
8719
- }
8720
- else if ( ! $.isArray( order[0] ) ) {
8721
- // Arguments passed in (list of 1D arrays)
8722
- order = Array.prototype.slice.call( arguments );
8723
- }
8724
- // otherwise a 2D array was passed in
8725
-
8726
- return this.iterator( 'table', function ( settings ) {
8727
- settings.aaSorting = order.slice();
8728
- } );
8729
- } );
8730
-
8731
-
8732
- /**
8733
- * Attach a sort listener to an element for a given column
8734
- *
8735
- * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8736
- * listener to. This can take the form of a single DOM node, a jQuery
8737
- * collection of nodes or a jQuery selector which will identify the node(s).
8738
- * @param {integer} column the column that a click on this node will sort on
8739
- * @param {function} [callback] callback function when sort is run
8740
- * @returns {DataTables.Api} this
8741
- */
8742
- _api_register( 'order.listener()', function ( node, column, callback ) {
8743
- return this.iterator( 'table', function ( settings ) {
8744
- _fnSortAttachListener( settings, node, column, callback );
8745
- } );
8746
- } );
8747
-
8748
-
8749
- // Order by the selected column(s)
8750
- _api_register( [
8751
- 'columns().order()',
8752
- 'column().order()'
8753
- ], function ( dir ) {
8754
- var that = this;
8755
-
8756
- return this.iterator( 'table', function ( settings, i ) {
8757
- var sort = [];
8758
-
8759
- $.each( that[i], function (j, col) {
8760
- sort.push( [ col, dir ] );
8761
- } );
8762
-
8763
- settings.aaSorting = sort;
8764
- } );
8765
- } );
8766
-
8767
-
8768
-
8769
- _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
8770
- var ctx = this.context;
8771
-
8772
- if ( input === undefined ) {
8773
- // get
8774
- return ctx.length !== 0 ?
8775
- ctx[0].oPreviousSearch.sSearch :
8776
- undefined;
8777
- }
8778
-
8779
- // set
8780
- return this.iterator( 'table', function ( settings ) {
8781
- if ( ! settings.oFeatures.bFilter ) {
8782
- return;
8783
- }
8784
-
8785
- _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
8786
- "sSearch": input+"",
8787
- "bRegex": regex === null ? false : regex,
8788
- "bSmart": smart === null ? true : smart,
8789
- "bCaseInsensitive": caseInsen === null ? true : caseInsen
8790
- } ), 1 );
8791
- } );
8792
- } );
8793
-
8794
-
8795
- _api_registerPlural(
8796
- 'columns().search()',
8797
- 'column().search()',
8798
- function ( input, regex, smart, caseInsen ) {
8799
- return this.iterator( 'column', function ( settings, column ) {
8800
- var preSearch = settings.aoPreSearchCols;
8801
-
8802
- if ( input === undefined ) {
8803
- // get
8804
- return preSearch[ column ].sSearch;
8805
- }
8806
-
8807
- // set
8808
- if ( ! settings.oFeatures.bFilter ) {
8809
- return;
8810
- }
8811
-
8812
- $.extend( preSearch[ column ], {
8813
- "sSearch": input+"",
8814
- "bRegex": regex === null ? false : regex,
8815
- "bSmart": smart === null ? true : smart,
8816
- "bCaseInsensitive": caseInsen === null ? true : caseInsen
8817
- } );
8818
-
8819
- _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
8820
- } );
8821
- }
8822
- );
8823
-
8824
- /*
8825
- * State API methods
8826
- */
8827
-
8828
- _api_register( 'state()', function () {
8829
- return this.context.length ?
8830
- this.context[0].oSavedState :
8831
- null;
8832
- } );
8833
-
8834
-
8835
- _api_register( 'state.clear()', function () {
8836
- return this.iterator( 'table', function ( settings ) {
8837
- // Save an empty object
8838
- settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
8839
- } );
8840
- } );
8841
-
8842
-
8843
- _api_register( 'state.loaded()', function () {
8844
- return this.context.length ?
8845
- this.context[0].oLoadedState :
8846
- null;
8847
- } );
8848
-
8849
-
8850
- _api_register( 'state.save()', function () {
8851
- return this.iterator( 'table', function ( settings ) {
8852
- _fnSaveState( settings );
8853
- } );
8854
- } );
8855
-
8856
-
8857
-
8858
- /**
8859
- * Provide a common method for plug-ins to check the version of DataTables being
8860
- * used, in order to ensure compatibility.
8861
- *
8862
- * @param {string} version Version string to check for, in the format "X.Y.Z".
8863
- * Note that the formats "X" and "X.Y" are also acceptable.
8864
- * @returns {boolean} true if this version of DataTables is greater or equal to
8865
- * the required version, or false if this version of DataTales is not
8866
- * suitable
8867
- * @static
8868
- * @dtopt API-Static
8869
- *
8870
- * @example
8871
- * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
8872
- */
8873
- DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
8874
- {
8875
- var aThis = DataTable.version.split('.');
8876
- var aThat = version.split('.');
8877
- var iThis, iThat;
8878
-
8879
- for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
8880
- iThis = parseInt( aThis[i], 10 ) || 0;
8881
- iThat = parseInt( aThat[i], 10 ) || 0;
8882
-
8883
- // Parts are the same, keep comparing
8884
- if (iThis === iThat) {
8885
- continue;
8886
- }
8887
-
8888
- // Parts are different, return immediately
8889
- return iThis > iThat;
8890
- }
8891
-
8892
- return true;
8893
- };
8894
-
8895
-
8896
- /**
8897
- * Check if a `<table>` node is a DataTable table already or not.
8898
- *
8899
- * @param {node|jquery|string} table Table node, jQuery object or jQuery
8900
- * selector for the table to test. Note that if more than more than one
8901
- * table is passed on, only the first will be checked
8902
- * @returns {boolean} true the table given is a DataTable, or false otherwise
8903
- * @static
8904
- * @dtopt API-Static
8905
- *
8906
- * @example
8907
- * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
8908
- * $('#example').dataTable();
8909
- * }
8910
- */
8911
- DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
8912
- {
8913
- var t = $(table).get(0);
8914
- var is = false;
8915
-
8916
- $.each( DataTable.settings, function (i, o) {
8917
- var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
8918
- var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
8919
-
8920
- if ( o.nTable === t || head === t || foot === t ) {
8921
- is = true;
8922
- }
8923
- } );
8924
-
8925
- return is;
8926
- };
8927
-
8928
-
8929
- /**
8930
- * Get all DataTable tables that have been initialised - optionally you can
8931
- * select to get only currently visible tables.
8932
- *
8933
- * @param {boolean} [visible=false] Flag to indicate if you want all (default)
8934
- * or visible tables only.
8935
- * @returns {array} Array of `table` nodes (not DataTable instances) which are
8936
- * DataTables
8937
- * @static
8938
- * @dtopt API-Static
8939
- *
8940
- * @example
8941
- * $.each( $.fn.dataTable.tables(true), function () {
8942
- * $(table).DataTable().columns.adjust();
8943
- * } );
8944
- */
8945
- DataTable.tables = DataTable.fnTables = function ( visible )
8946
- {
8947
- var api = false;
8948
-
8949
- if ( $.isPlainObject( visible ) ) {
8950
- api = visible.api;
8951
- visible = visible.visible;
8952
- }
8953
-
8954
- var a = $.map( DataTable.settings, function (o) {
8955
- if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
8956
- return o.nTable;
8957
- }
8958
- } );
8959
-
8960
- return api ?
8961
- new _Api( a ) :
8962
- a;
8963
- };
8964
-
8965
-
8966
- /**
8967
- * DataTables utility methods
8968
- *
8969
- * This namespace provides helper methods that DataTables uses internally to
8970
- * create a DataTable, but which are not exclusively used only for DataTables.
8971
- * These methods can be used by extension authors to save the duplication of
8972
- * code.
8973
- *
8974
- * @namespace
8975
- */
8976
- DataTable.util = {
8977
- /**
8978
- * Throttle the calls to a function. Arguments and context are maintained
8979
- * for the throttled function.
8980
- *
8981
- * @param {function} fn Function to be called
8982
- * @param {integer} freq Call frequency in mS
8983
- * @return {function} Wrapped function
8984
- */
8985
- throttle: _fnThrottle,
8986
-
8987
-
8988
- /**
8989
- * Escape a string such that it can be used in a regular expression
8990
- *
8991
- * @param {string} sVal string to escape
8992
- * @returns {string} escaped string
8993
- */
8994
- escapeRegex: _fnEscapeRegex
8995
- };
8996
-
8997
-
8998
- /**
8999
- * Convert from camel case parameters to Hungarian notation. This is made public
9000
- * for the extensions to provide the same ability as DataTables core to accept
9001
- * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9002
- * parameters.
9003
- *
9004
- * @param {object} src The model object which holds all parameters that can be
9005
- * mapped.
9006
- * @param {object} user The object to convert from camel case to Hungarian.
9007
- * @param {boolean} force When set to `true`, properties which already have a
9008
- * Hungarian value in the `user` object will be overwritten. Otherwise they
9009
- * won't be.
9010
- */
9011
- DataTable.camelToHungarian = _fnCamelToHungarian;
9012
-
9013
-
9014
-
9015
- /**
9016
- *
9017
- */
9018
- _api_register( '$()', function ( selector, opts ) {
9019
- var
9020
- rows = this.rows( opts ).nodes(), // Get all rows
9021
- jqRows = $(rows);
9022
-
9023
- return $( [].concat(
9024
- jqRows.filter( selector ).toArray(),
9025
- jqRows.find( selector ).toArray()
9026
- ) );
9027
- } );
9028
-
9029
-
9030
- // jQuery functions to operate on the tables
9031
- $.each( [ 'on', 'one', 'off' ], function (i, key) {
9032
- _api_register( key+'()', function ( /* event, handler */ ) {
9033
- var args = Array.prototype.slice.call(arguments);
9034
-
9035
- // Add the `dt` namespace automatically if it isn't already present
9036
- if ( ! args[0].match(/\.dt\b/) ) {
9037
- args[0] += '.dt';
9038
- }
9039
-
9040
- var inst = $( this.tables().nodes() );
9041
- inst[key].apply( inst, args );
9042
- return this;
9043
- } );
9044
- } );
9045
-
9046
-
9047
- _api_register( 'clear()', function () {
9048
- return this.iterator( 'table', function ( settings ) {
9049
- _fnClearTable( settings );
9050
- } );
9051
- } );
9052
-
9053
-
9054
- _api_register( 'settings()', function () {
9055
- return new _Api( this.context, this.context );
9056
- } );
9057
-
9058
-
9059
- _api_register( 'init()', function () {
9060
- var ctx = this.context;
9061
- return ctx.length ? ctx[0].oInit : null;
9062
- } );
9063
-
9064
-
9065
- _api_register( 'data()', function () {
9066
- return this.iterator( 'table', function ( settings ) {
9067
- return _pluck( settings.aoData, '_aData' );
9068
- } ).flatten();
9069
- } );
9070
-
9071
-
9072
- _api_register( 'destroy()', function ( remove ) {
9073
- remove = remove || false;
9074
-
9075
- return this.iterator( 'table', function ( settings ) {
9076
- var orig = settings.nTableWrapper.parentNode;
9077
- var classes = settings.oClasses;
9078
- var table = settings.nTable;
9079
- var tbody = settings.nTBody;
9080
- var thead = settings.nTHead;
9081
- var tfoot = settings.nTFoot;
9082
- var jqTable = $(table);
9083
- var jqTbody = $(tbody);
9084
- var jqWrapper = $(settings.nTableWrapper);
9085
- var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
9086
- var i, ien;
9087
-
9088
- // Flag to note that the table is currently being destroyed - no action
9089
- // should be taken
9090
- settings.bDestroying = true;
9091
-
9092
- // Fire off the destroy callbacks for plug-ins etc
9093
- _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9094
-
9095
- // If not being removed from the document, make all columns visible
9096
- if ( ! remove ) {
9097
- new _Api( settings ).columns().visible( true );
9098
- }
9099
-
9100
- // Blitz all `DT` namespaced events (these are internal events, the
9101
- // lowercase, `dt` events are user subscribed and they are responsible
9102
- // for removing them
9103
- jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
9104
- $(window).unbind('.DT-'+settings.sInstance);
9105
-
9106
- // When scrolling we had to break the table up - restore it
9107
- if ( table != thead.parentNode ) {
9108
- jqTable.children('thead').detach();
9109
- jqTable.append( thead );
9110
- }
9111
-
9112
- if ( tfoot && table != tfoot.parentNode ) {
9113
- jqTable.children('tfoot').detach();
9114
- jqTable.append( tfoot );
9115
- }
9116
-
9117
- settings.aaSorting = [];
9118
- settings.aaSortingFixed = [];
9119
- _fnSortingClasses( settings );
9120
-
9121
- $( rows ).removeClass( settings.asStripeClasses.join(' ') );
9122
-
9123
- $('th, td', thead).removeClass( classes.sSortable+' '+
9124
- classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9125
- );
9126
-
9127
- if ( settings.bJUI ) {
9128
- $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
9129
- $('th, td', thead).each( function () {
9130
- var wrapper = $('div.'+classes.sSortJUIWrapper, this);
9131
- $(this).append( wrapper.contents() );
9132
- wrapper.detach();
9133
- } );
9134
- }
9135
-
9136
- // Add the TR elements back into the table in their original order
9137
- jqTbody.children().detach();
9138
- jqTbody.append( rows );
9139
-
9140
- // Remove the DataTables generated nodes, events and classes
9141
- var removedMethod = remove ? 'remove' : 'detach';
9142
- jqTable[ removedMethod ]();
9143
- jqWrapper[ removedMethod ]();
9144
-
9145
- // If we need to reattach the table to the document
9146
- if ( ! remove && orig ) {
9147
- // insertBefore acts like appendChild if !arg[1]
9148
- orig.insertBefore( table, settings.nTableReinsertBefore );
9149
-
9150
- // Restore the width of the original table - was read from the style property,
9151
- // so we can restore directly to that
9152
- jqTable
9153
- .css( 'width', settings.sDestroyWidth )
9154
- .removeClass( classes.sTable );
9155
-
9156
- // If the were originally stripe classes - then we add them back here.
9157
- // Note this is not fool proof (for example if not all rows had stripe
9158
- // classes - but it's a good effort without getting carried away
9159
- ien = settings.asDestroyStripes.length;
9160
-
9161
- if ( ien ) {
9162
- jqTbody.children().each( function (i) {
9163
- $(this).addClass( settings.asDestroyStripes[i % ien] );
9164
- } );
9165
- }
9166
- }
9167
-
9168
- /* Remove the settings object from the settings array */
9169
- var idx = $.inArray( settings, DataTable.settings );
9170
- if ( idx !== -1 ) {
9171
- DataTable.settings.splice( idx, 1 );
9172
- }
9173
- } );
9174
- } );
9175
-
9176
-
9177
- // Add the `every()` method for rows, columns and cells in a compact form
9178
- $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9179
- _api_register( type+'s().every()', function ( fn ) {
9180
- return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9181
- // Rows and columns:
9182
- // arg1 - index
9183
- // arg2 - table counter
9184
- // arg3 - loop counter
9185
- // arg4 - undefined
9186
- // Cells:
9187
- // arg1 - row index
9188
- // arg2 - column index
9189
- // arg3 - table counter
9190
- // arg4 - loop counter
9191
- fn.call(
9192
- new _Api( settings )[ type ]( arg1, type==='cell' ? arg2 : undefined ),
9193
- arg1, arg2, arg3, arg4
9194
- );
9195
- } );
9196
- } );
9197
- } );
9198
-
9199
-
9200
- // i18n method for extensions to be able to use the language object from the
9201
- // DataTable
9202
- _api_register( 'i18n()', function ( token, def, plural ) {
9203
- var ctx = this.context[0];
9204
- var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9205
-
9206
- if ( resolved === undefined ) {
9207
- resolved = def;
9208
- }
9209
-
9210
- if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9211
- resolved = resolved[ plural ] !== undefined ?
9212
- resolved[ plural ] :
9213
- resolved._;
9214
- }
9215
-
9216
- return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9217
- } );
9218
-
9219
- /**
9220
- * Version string for plug-ins to check compatibility. Allowed format is
9221
- * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9222
- * only for non-release builds. See http://semver.org/ for more information.
9223
- * @member
9224
- * @type string
9225
- * @default Version number
9226
- */
9227
- DataTable.version = "1.10.8";
9228
-
9229
- /**
9230
- * Private data store, containing all of the settings objects that are
9231
- * created for the tables on a given page.
9232
- *
9233
- * Note that the `DataTable.settings` object is aliased to
9234
- * `jQuery.fn.dataTableExt` through which it may be accessed and
9235
- * manipulated, or `jQuery.fn.dataTable.settings`.
9236
- * @member
9237
- * @type array
9238
- * @default []
9239
- * @private
9240
- */
9241
- DataTable.settings = [];
9242
-
9243
- /**
9244
- * Object models container, for the various models that DataTables has
9245
- * available to it. These models define the objects that are used to hold
9246
- * the active state and configuration of the table.
9247
- * @namespace
9248
- */
9249
- DataTable.models = {};
9250
-
9251
-
9252
-
9253
- /**
9254
- * Template object for the way in which DataTables holds information about
9255
- * search information for the global filter and individual column filters.
9256
- * @namespace
9257
- */
9258
- DataTable.models.oSearch = {
9259
- /**
9260
- * Flag to indicate if the filtering should be case insensitive or not
9261
- * @type boolean
9262
- * @default true
9263
- */
9264
- "bCaseInsensitive": true,
9265
-
9266
- /**
9267
- * Applied search term
9268
- * @type string
9269
- * @default <i>Empty string</i>
9270
- */
9271
- "sSearch": "",
9272
-
9273
- /**
9274
- * Flag to indicate if the search term should be interpreted as a
9275
- * regular expression (true) or not (false) and therefore and special
9276
- * regex characters escaped.
9277
- * @type boolean
9278
- * @default false
9279
- */
9280
- "bRegex": false,
9281
-
9282
- /**
9283
- * Flag to indicate if DataTables is to use its smart filtering or not.
9284
- * @type boolean
9285
- * @default true
9286
- */
9287
- "bSmart": true
9288
- };
9289
-
9290
-
9291
-
9292
-
9293
- /**
9294
- * Template object for the way in which DataTables holds information about
9295
- * each individual row. This is the object format used for the settings
9296
- * aoData array.
9297
- * @namespace
9298
- */
9299
- DataTable.models.oRow = {
9300
- /**
9301
- * TR element for the row
9302
- * @type node
9303
- * @default null
9304
- */
9305
- "nTr": null,
9306
-
9307
- /**
9308
- * Array of TD elements for each row. This is null until the row has been
9309
- * created.
9310
- * @type array nodes
9311
- * @default []
9312
- */
9313
- "anCells": null,
9314
-
9315
- /**
9316
- * Data object from the original data source for the row. This is either
9317
- * an array if using the traditional form of DataTables, or an object if
9318
- * using mData options. The exact type will depend on the passed in
9319
- * data from the data source, or will be an array if using DOM a data
9320
- * source.
9321
- * @type array|object
9322
- * @default []
9323
- */
9324
- "_aData": [],
9325
-
9326
- /**
9327
- * Sorting data cache - this array is ostensibly the same length as the
9328
- * number of columns (although each index is generated only as it is
9329
- * needed), and holds the data that is used for sorting each column in the
9330
- * row. We do this cache generation at the start of the sort in order that
9331
- * the formatting of the sort data need be done only once for each cell
9332
- * per sort. This array should not be read from or written to by anything
9333
- * other than the master sorting methods.
9334
- * @type array
9335
- * @default null
9336
- * @private
9337
- */
9338
- "_aSortData": null,
9339
-
9340
- /**
9341
- * Per cell filtering data cache. As per the sort data cache, used to
9342
- * increase the performance of the filtering in DataTables
9343
- * @type array
9344
- * @default null
9345
- * @private
9346
- */
9347
- "_aFilterData": null,
9348
-
9349
- /**
9350
- * Filtering data cache. This is the same as the cell filtering cache, but
9351
- * in this case a string rather than an array. This is easily computed with
9352
- * a join on `_aFilterData`, but is provided as a cache so the join isn't
9353
- * needed on every search (memory traded for performance)
9354
- * @type array
9355
- * @default null
9356
- * @private
9357
- */
9358
- "_sFilterRow": null,
9359
-
9360
- /**
9361
- * Cache of the class name that DataTables has applied to the row, so we
9362
- * can quickly look at this variable rather than needing to do a DOM check
9363
- * on className for the nTr property.
9364
- * @type string
9365
- * @default <i>Empty string</i>
9366
- * @private
9367
- */
9368
- "_sRowStripe": "",
9369
-
9370
- /**
9371
- * Denote if the original data source was from the DOM, or the data source
9372
- * object. This is used for invalidating data, so DataTables can
9373
- * automatically read data from the original source, unless uninstructed
9374
- * otherwise.
9375
- * @type string
9376
- * @default null
9377
- * @private
9378
- */
9379
- "src": null,
9380
-
9381
- /**
9382
- * Index in the aoData array. This saves an indexOf lookup when we have the
9383
- * object, but want to know the index
9384
- * @type integer
9385
- * @default -1
9386
- * @private
9387
- */
9388
- "idx": -1
9389
- };
9390
-
9391
-
9392
- /**
9393
- * Template object for the column information object in DataTables. This object
9394
- * is held in the settings aoColumns array and contains all the information that
9395
- * DataTables needs about each individual column.
9396
- *
9397
- * Note that this object is related to {@link DataTable.defaults.column}
9398
- * but this one is the internal data store for DataTables's cache of columns.
9399
- * It should NOT be manipulated outside of DataTables. Any configuration should
9400
- * be done through the initialisation options.
9401
- * @namespace
9402
- */
9403
- DataTable.models.oColumn = {
9404
- /**
9405
- * Column index. This could be worked out on-the-fly with $.inArray, but it
9406
- * is faster to just hold it as a variable
9407
- * @type integer
9408
- * @default null
9409
- */
9410
- "idx": null,
9411
-
9412
- /**
9413
- * A list of the columns that sorting should occur on when this column
9414
- * is sorted. That this property is an array allows multi-column sorting
9415
- * to be defined for a column (for example first name / last name columns
9416
- * would benefit from this). The values are integers pointing to the
9417
- * columns to be sorted on (typically it will be a single integer pointing
9418
- * at itself, but that doesn't need to be the case).
9419
- * @type array
9420
- */
9421
- "aDataSort": null,
9422
-
9423
- /**
9424
- * Define the sorting directions that are applied to the column, in sequence
9425
- * as the column is repeatedly sorted upon - i.e. the first value is used
9426
- * as the sorting direction when the column if first sorted (clicked on).
9427
- * Sort it again (click again) and it will move on to the next index.
9428
- * Repeat until loop.
9429
- * @type array
9430
- */
9431
- "asSorting": null,
9432
-
9433
- /**
9434
- * Flag to indicate if the column is searchable, and thus should be included
9435
- * in the filtering or not.
9436
- * @type boolean
9437
- */
9438
- "bSearchable": null,
9439
-
9440
- /**
9441
- * Flag to indicate if the column is sortable or not.
9442
- * @type boolean
9443
- */
9444
- "bSortable": null,
9445
-
9446
- /**
9447
- * Flag to indicate if the column is currently visible in the table or not
9448
- * @type boolean
9449
- */
9450
- "bVisible": null,
9451
-
9452
- /**
9453
- * Store for manual type assignment using the `column.type` option. This
9454
- * is held in store so we can manipulate the column's `sType` property.
9455
- * @type string
9456
- * @default null
9457
- * @private
9458
- */
9459
- "_sManualType": null,
9460
-
9461
- /**
9462
- * Flag to indicate if HTML5 data attributes should be used as the data
9463
- * source for filtering or sorting. True is either are.
9464
- * @type boolean
9465
- * @default false
9466
- * @private
9467
- */
9468
- "_bAttrSrc": false,
9469
-
9470
- /**
9471
- * Developer definable function that is called whenever a cell is created (Ajax source,
9472
- * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9473
- * allowing you to modify the DOM element (add background colour for example) when the
9474
- * element is available.
9475
- * @type function
9476
- * @param {element} nTd The TD node that has been created
9477
- * @param {*} sData The Data for the cell
9478
- * @param {array|object} oData The data for the whole row
9479
- * @param {int} iRow The row index for the aoData data store
9480
- * @default null
9481
- */
9482
- "fnCreatedCell": null,
9483
-
9484
- /**
9485
- * Function to get data from a cell in a column. You should <b>never</b>
9486
- * access data directly through _aData internally in DataTables - always use
9487
- * the method attached to this property. It allows mData to function as
9488
- * required. This function is automatically assigned by the column
9489
- * initialisation method
9490
- * @type function
9491
- * @param {array|object} oData The data array/object for the array
9492
- * (i.e. aoData[]._aData)
9493
- * @param {string} sSpecific The specific data type you want to get -
9494
- * 'display', 'type' 'filter' 'sort'
9495
- * @returns {*} The data for the cell from the given row's data
9496
- * @default null
9497
- */
9498
- "fnGetData": null,
9499
-
9500
- /**
9501
- * Function to set data for a cell in the column. You should <b>never</b>
9502
- * set the data directly to _aData internally in DataTables - always use
9503
- * this method. It allows mData to function as required. This function
9504
- * is automatically assigned by the column initialisation method
9505
- * @type function
9506
- * @param {array|object} oData The data array/object for the array
9507
- * (i.e. aoData[]._aData)
9508
- * @param {*} sValue Value to set
9509
- * @default null
9510
- */
9511
- "fnSetData": null,
9512
-
9513
- /**
9514
- * Property to read the value for the cells in the column from the data
9515
- * source array / object. If null, then the default content is used, if a
9516
- * function is given then the return from the function is used.
9517
- * @type function|int|string|null
9518
- * @default null
9519
- */
9520
- "mData": null,
9521
-
9522
- /**
9523
- * Partner property to mData which is used (only when defined) to get
9524
- * the data - i.e. it is basically the same as mData, but without the
9525
- * 'set' option, and also the data fed to it is the result from mData.
9526
- * This is the rendering method to match the data method of mData.
9527
- * @type function|int|string|null
9528
- * @default null
9529
- */
9530
- "mRender": null,
9531
-
9532
- /**
9533
- * Unique header TH/TD element for this column - this is what the sorting
9534
- * listener is attached to (if sorting is enabled.)
9535
- * @type node
9536
- * @default null
9537
- */
9538
- "nTh": null,
9539
-
9540
- /**
9541
- * Unique footer TH/TD element for this column (if there is one). Not used
9542
- * in DataTables as such, but can be used for plug-ins to reference the
9543
- * footer for each column.
9544
- * @type node
9545
- * @default null
9546
- */
9547
- "nTf": null,
9548
-
9549
- /**
9550
- * The class to apply to all TD elements in the table's TBODY for the column
9551
- * @type string
9552
- * @default null
9553
- */
9554
- "sClass": null,
9555
-
9556
- /**
9557
- * When DataTables calculates the column widths to assign to each column,
9558
- * it finds the longest string in each column and then constructs a
9559
- * temporary table and reads the widths from that. The problem with this
9560
- * is that "mmm" is much wider then "iiii", but the latter is a longer
9561
- * string - thus the calculation can go wrong (doing it properly and putting
9562
- * it into an DOM object and measuring that is horribly(!) slow). Thus as
9563
- * a "work around" we provide this option. It will append its value to the
9564
- * text that is found to be the longest string for the column - i.e. padding.
9565
- * @type string
9566
- */
9567
- "sContentPadding": null,
9568
-
9569
- /**
9570
- * Allows a default value to be given for a column's data, and will be used
9571
- * whenever a null data source is encountered (this can be because mData
9572
- * is set to null, or because the data source itself is null).
9573
- * @type string
9574
- * @default null
9575
- */
9576
- "sDefaultContent": null,
9577
-
9578
- /**
9579
- * Name for the column, allowing reference to the column by name as well as
9580
- * by index (needs a lookup to work by name).
9581
- * @type string
9582
- */
9583
- "sName": null,
9584
-
9585
- /**
9586
- * Custom sorting data type - defines which of the available plug-ins in
9587
- * afnSortData the custom sorting will use - if any is defined.
9588
- * @type string
9589
- * @default std
9590
- */
9591
- "sSortDataType": 'std',
9592
-
9593
- /**
9594
- * Class to be applied to the header element when sorting on this column
9595
- * @type string
9596
- * @default null
9597
- */
9598
- "sSortingClass": null,
9599
-
9600
- /**
9601
- * Class to be applied to the header element when sorting on this column -
9602
- * when jQuery UI theming is used.
9603
- * @type string
9604
- * @default null
9605
- */
9606
- "sSortingClassJUI": null,
9607
-
9608
- /**
9609
- * Title of the column - what is seen in the TH element (nTh).
9610
- * @type string
9611
- */
9612
- "sTitle": null,
9613
-
9614
- /**
9615
- * Column sorting and filtering type
9616
- * @type string
9617
- * @default null
9618
- */
9619
- "sType": null,
9620
-
9621
- /**
9622
- * Width of the column
9623
- * @type string
9624
- * @default null
9625
- */
9626
- "sWidth": null,
9627
-
9628
- /**
9629
- * Width of the column when it was first "encountered"
9630
- * @type string
9631
- * @default null
9632
- */
9633
- "sWidthOrig": null
9634
- };
9635
-
9636
-
9637
- /*
9638
- * Developer note: The properties of the object below are given in Hungarian
9639
- * notation, that was used as the interface for DataTables prior to v1.10, however
9640
- * from v1.10 onwards the primary interface is camel case. In order to avoid
9641
- * breaking backwards compatibility utterly with this change, the Hungarian
9642
- * version is still, internally the primary interface, but is is not documented
9643
- * - hence the @name tags in each doc comment. This allows a Javascript function
9644
- * to create a map from Hungarian notation to camel case (going the other direction
9645
- * would require each property to be listed, which would at around 3K to the size
9646
- * of DataTables, while this method is about a 0.5K hit.
9647
- *
9648
- * Ultimately this does pave the way for Hungarian notation to be dropped
9649
- * completely, but that is a massive amount of work and will break current
9650
- * installs (therefore is on-hold until v2).
9651
- */
9652
-
9653
- /**
9654
- * Initialisation options that can be given to DataTables at initialisation
9655
- * time.
9656
- * @namespace
9657
- */
9658
- DataTable.defaults = {
9659
- /**
9660
- * An array of data to use for the table, passed in at initialisation which
9661
- * will be used in preference to any data which is already in the DOM. This is
9662
- * particularly useful for constructing tables purely in Javascript, for
9663
- * example with a custom Ajax call.
9664
- * @type array
9665
- * @default null
9666
- *
9667
- * @dtopt Option
9668
- * @name DataTable.defaults.data
9669
- *
9670
- * @example
9671
- * // Using a 2D array data source
9672
- * $(document).ready( function () {
9673
- * $('#example').dataTable( {
9674
- * "data": [
9675
- * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9676
- * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9677
- * ],
9678
- * "columns": [
9679
- * { "title": "Engine" },
9680
- * { "title": "Browser" },
9681
- * { "title": "Platform" },
9682
- * { "title": "Version" },
9683
- * { "title": "Grade" }
9684
- * ]
9685
- * } );
9686
- * } );
9687
- *
9688
- * @example
9689
- * // Using an array of objects as a data source (`data`)
9690
- * $(document).ready( function () {
9691
- * $('#example').dataTable( {
9692
- * "data": [
9693
- * {
9694
- * "engine": "Trident",
9695
- * "browser": "Internet Explorer 4.0",
9696
- * "platform": "Win 95+",
9697
- * "version": 4,
9698
- * "grade": "X"
9699
- * },
9700
- * {
9701
- * "engine": "Trident",
9702
- * "browser": "Internet Explorer 5.0",
9703
- * "platform": "Win 95+",
9704
- * "version": 5,
9705
- * "grade": "C"
9706
- * }
9707
- * ],
9708
- * "columns": [
9709
- * { "title": "Engine", "data": "engine" },
9710
- * { "title": "Browser", "data": "browser" },
9711
- * { "title": "Platform", "data": "platform" },
9712
- * { "title": "Version", "data": "version" },
9713
- * { "title": "Grade", "data": "grade" }
9714
- * ]
9715
- * } );
9716
- * } );
9717
- */
9718
- "aaData": null,
9719
-
9720
-
9721
- /**
9722
- * If ordering is enabled, then DataTables will perform a first pass sort on
9723
- * initialisation. You can define which column(s) the sort is performed
9724
- * upon, and the sorting direction, with this variable. The `sorting` array
9725
- * should contain an array for each column to be sorted initially containing
9726
- * the column's index and a direction string ('asc' or 'desc').
9727
- * @type array
9728
- * @default [[0,'asc']]
9729
- *
9730
- * @dtopt Option
9731
- * @name DataTable.defaults.order
9732
- *
9733
- * @example
9734
- * // Sort by 3rd column first, and then 4th column
9735
- * $(document).ready( function() {
9736
- * $('#example').dataTable( {
9737
- * "order": [[2,'asc'], [3,'desc']]
9738
- * } );
9739
- * } );
9740
- *
9741
- * // No initial sorting
9742
- * $(document).ready( function() {
9743
- * $('#example').dataTable( {
9744
- * "order": []
9745
- * } );
9746
- * } );
9747
- */
9748
- "aaSorting": [[0,'asc']],
9749
-
9750
-
9751
- /**
9752
- * This parameter is basically identical to the `sorting` parameter, but
9753
- * cannot be overridden by user interaction with the table. What this means
9754
- * is that you could have a column (visible or hidden) which the sorting
9755
- * will always be forced on first - any sorting after that (from the user)
9756
- * will then be performed as required. This can be useful for grouping rows
9757
- * together.
9758
- * @type array
9759
- * @default null
9760
- *
9761
- * @dtopt Option
9762
- * @name DataTable.defaults.orderFixed
9763
- *
9764
- * @example
9765
- * $(document).ready( function() {
9766
- * $('#example').dataTable( {
9767
- * "orderFixed": [[0,'asc']]
9768
- * } );
9769
- * } )
9770
- */
9771
- "aaSortingFixed": [],
9772
-
9773
-
9774
- /**
9775
- * DataTables can be instructed to load data to display in the table from a
9776
- * Ajax source. This option defines how that Ajax call is made and where to.
9777
- *
9778
- * The `ajax` property has three different modes of operation, depending on
9779
- * how it is defined. These are:
9780
- *
9781
- * * `string` - Set the URL from where the data should be loaded from.
9782
- * * `object` - Define properties for `jQuery.ajax`.
9783
- * * `function` - Custom data get function
9784
- *
9785
- * `string`
9786
- * --------
9787
- *
9788
- * As a string, the `ajax` property simply defines the URL from which
9789
- * DataTables will load data.
9790
- *
9791
- * `object`
9792
- * --------
9793
- *
9794
- * As an object, the parameters in the object are passed to
9795
- * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9796
- * of the Ajax request. DataTables has a number of default parameters which
9797
- * you can override using this option. Please refer to the jQuery
9798
- * documentation for a full description of the options available, although
9799
- * the following parameters provide additional options in DataTables or
9800
- * require special consideration:
9801
- *
9802
- * * `data` - As with jQuery, `data` can be provided as an object, but it
9803
- * can also be used as a function to manipulate the data DataTables sends
9804
- * to the server. The function takes a single parameter, an object of
9805
- * parameters with the values that DataTables has readied for sending. An
9806
- * object may be returned which will be merged into the DataTables
9807
- * defaults, or you can add the items to the object that was passed in and
9808
- * not return anything from the function. This supersedes `fnServerParams`
9809
- * from DataTables 1.9-.
9810
- *
9811
- * * `dataSrc` - By default DataTables will look for the property `data` (or
9812
- * `aaData` for compatibility with DataTables 1.9-) when obtaining data
9813
- * from an Ajax source or for server-side processing - this parameter
9814
- * allows that property to be changed. You can use Javascript dotted
9815
- * object notation to get a data source for multiple levels of nesting, or
9816
- * it my be used as a function. As a function it takes a single parameter,
9817
- * the JSON returned from the server, which can be manipulated as
9818
- * required, with the returned value being that used by DataTables as the
9819
- * data source for the table. This supersedes `sAjaxDataProp` from
9820
- * DataTables 1.9-.
9821
- *
9822
- * * `success` - Should not be overridden it is used internally in
9823
- * DataTables. To manipulate / transform the data returned by the server
9824
- * use `ajax.dataSrc`, or use `ajax` as a function (see below).
9825
- *
9826
- * `function`
9827
- * ----------
9828
- *
9829
- * As a function, making the Ajax call is left up to yourself allowing
9830
- * complete control of the Ajax request. Indeed, if desired, a method other
9831
- * than Ajax could be used to obtain the required data, such as Web storage
9832
- * or an AIR database.
9833
- *
9834
- * The function is given four parameters and no return is required. The
9835
- * parameters are:
9836
- *
9837
- * 1. _object_ - Data to send to the server
9838
- * 2. _function_ - Callback function that must be executed when the required
9839
- * data has been obtained. That data should be passed into the callback
9840
- * as the only parameter
9841
- * 3. _object_ - DataTables settings object for the table
9842
- *
9843
- * Note that this supersedes `fnServerData` from DataTables 1.9-.
9844
- *
9845
- * @type string|object|function
9846
- * @default null
9847
- *
9848
- * @dtopt Option
9849
- * @name DataTable.defaults.ajax
9850
- * @since 1.10.0
9851
- *
9852
- * @example
9853
- * // Get JSON data from a file via Ajax.
9854
- * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
9855
- * $('#example').dataTable( {
9856
- * "ajax": "data.json"
9857
- * } );
9858
- *
9859
- * @example
9860
- * // Get JSON data from a file via Ajax, using `dataSrc` to change
9861
- * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
9862
- * $('#example').dataTable( {
9863
- * "ajax": {
9864
- * "url": "data.json",
9865
- * "dataSrc": "tableData"
9866
- * }
9867
- * } );
9868
- *
9869
- * @example
9870
- * // Get JSON data from a file via Ajax, using `dataSrc` to read data
9871
- * // from a plain array rather than an array in an object
9872
- * $('#example').dataTable( {
9873
- * "ajax": {
9874
- * "url": "data.json",
9875
- * "dataSrc": ""
9876
- * }
9877
- * } );
9878
- *
9879
- * @example
9880
- * // Manipulate the data returned from the server - add a link to data
9881
- * // (note this can, should, be done using `render` for the column - this
9882
- * // is just a simple example of how the data can be manipulated).
9883
- * $('#example').dataTable( {
9884
- * "ajax": {
9885
- * "url": "data.json",
9886
- * "dataSrc": function ( json ) {
9887
- * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
9888
- * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
9889
- * }
9890
- * return json;
9891
- * }
9892
- * }
9893
- * } );
9894
- *
9895
- * @example
9896
- * // Add data to the request
9897
- * $('#example').dataTable( {
9898
- * "ajax": {
9899
- * "url": "data.json",
9900
- * "data": function ( d ) {
9901
- * return {
9902
- * "extra_search": $('#extra').val()
9903
- * };
9904
- * }
9905
- * }
9906
- * } );
9907
- *
9908
- * @example
9909
- * // Send request as POST
9910
- * $('#example').dataTable( {
9911
- * "ajax": {
9912
- * "url": "data.json",
9913
- * "type": "POST"
9914
- * }
9915
- * } );
9916
- *
9917
- * @example
9918
- * // Get the data from localStorage (could interface with a form for
9919
- * // adding, editing and removing rows).
9920
- * $('#example').dataTable( {
9921
- * "ajax": function (data, callback, settings) {
9922
- * callback(
9923
- * JSON.parse( localStorage.getItem('dataTablesData') )
9924
- * );
9925
- * }
9926
- * } );
9927
- */
9928
- "ajax": null,
9929
-
9930
-
9931
- /**
9932
- * This parameter allows you to readily specify the entries in the length drop
9933
- * down menu that DataTables shows when pagination is enabled. It can be
9934
- * either a 1D array of options which will be used for both the displayed
9935
- * option and the value, or a 2D array which will use the array in the first
9936
- * position as the value, and the array in the second position as the
9937
- * displayed options (useful for language strings such as 'All').
9938
- *
9939
- * Note that the `pageLength` property will be automatically set to the
9940
- * first value given in this array, unless `pageLength` is also provided.
9941
- * @type array
9942
- * @default [ 10, 25, 50, 100 ]
9943
- *
9944
- * @dtopt Option
9945
- * @name DataTable.defaults.lengthMenu
9946
- *
9947
- * @example
9948
- * $(document).ready( function() {
9949
- * $('#example').dataTable( {
9950
- * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
9951
- * } );
9952
- * } );
9953
- */
9954
- "aLengthMenu": [ 10, 25, 50, 100 ],
9955
-
9956
-
9957
- /**
9958
- * The `columns` option in the initialisation parameter allows you to define
9959
- * details about the way individual columns behave. For a full list of
9960
- * column options that can be set, please see
9961
- * {@link DataTable.defaults.column}. Note that if you use `columns` to
9962
- * define your columns, you must have an entry in the array for every single
9963
- * column that you have in your table (these can be null if you don't which
9964
- * to specify any options).
9965
- * @member
9966
- *
9967
- * @name DataTable.defaults.column
9968
- */
9969
- "aoColumns": null,
9970
-
9971
- /**
9972
- * Very similar to `columns`, `columnDefs` allows you to target a specific
9973
- * column, multiple columns, or all columns, using the `targets` property of
9974
- * each object in the array. This allows great flexibility when creating
9975
- * tables, as the `columnDefs` arrays can be of any length, targeting the
9976
- * columns you specifically want. `columnDefs` may use any of the column
9977
- * options available: {@link DataTable.defaults.column}, but it _must_
9978
- * have `targets` defined in each object in the array. Values in the `targets`
9979
- * array may be:
9980
- * <ul>
9981
- * <li>a string - class name will be matched on the TH for the column</li>
9982
- * <li>0 or a positive integer - column index counting from the left</li>
9983
- * <li>a negative integer - column index counting from the right</li>
9984
- * <li>the string "_all" - all columns (i.e. assign a default)</li>
9985
- * </ul>
9986
- * @member
9987
- *
9988
- * @name DataTable.defaults.columnDefs
9989
- */
9990
- "aoColumnDefs": null,
9991
-
9992
-
9993
- /**
9994
- * Basically the same as `search`, this parameter defines the individual column
9995
- * filtering state at initialisation time. The array must be of the same size
9996
- * as the number of columns, and each element be an object with the parameters
9997
- * `search` and `escapeRegex` (the latter is optional). 'null' is also
9998
- * accepted and the default will be used.
9999
- * @type array
10000
- * @default []
10001
- *
10002
- * @dtopt Option
10003
- * @name DataTable.defaults.searchCols
10004
- *
10005
- * @example
10006
- * $(document).ready( function() {
10007
- * $('#example').dataTable( {
10008
- * "searchCols": [
10009
- * null,
10010
- * { "search": "My filter" },
10011
- * null,
10012
- * { "search": "^[0-9]", "escapeRegex": false }
10013
- * ]
10014
- * } );
10015
- * } )
10016
- */
10017
- "aoSearchCols": [],
10018
-
10019
-
10020
- /**
10021
- * An array of CSS classes that should be applied to displayed rows. This
10022
- * array may be of any length, and DataTables will apply each class
10023
- * sequentially, looping when required.
10024
- * @type array
10025
- * @default null <i>Will take the values determined by the `oClasses.stripe*`
10026
- * options</i>
10027
- *
10028
- * @dtopt Option
10029
- * @name DataTable.defaults.stripeClasses
10030
- *
10031
- * @example
10032
- * $(document).ready( function() {
10033
- * $('#example').dataTable( {
10034
- * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10035
- * } );
10036
- * } )
10037
- */
10038
- "asStripeClasses": null,
10039
-
10040
-
10041
- /**
10042
- * Enable or disable automatic column width calculation. This can be disabled
10043
- * as an optimisation (it takes some time to calculate the widths) if the
10044
- * tables widths are passed in using `columns`.
10045
- * @type boolean
10046
- * @default true
10047
- *
10048
- * @dtopt Features
10049
- * @name DataTable.defaults.autoWidth
10050
- *
10051
- * @example
10052
- * $(document).ready( function () {
10053
- * $('#example').dataTable( {
10054
- * "autoWidth": false
10055
- * } );
10056
- * } );
10057
- */
10058
- "bAutoWidth": true,
10059
-
10060
-
10061
- /**
10062
- * Deferred rendering can provide DataTables with a huge speed boost when you
10063
- * are using an Ajax or JS data source for the table. This option, when set to
10064
- * true, will cause DataTables to defer the creation of the table elements for
10065
- * each row until they are needed for a draw - saving a significant amount of
10066
- * time.
10067
- * @type boolean
10068
- * @default false
10069
- *
10070
- * @dtopt Features
10071
- * @name DataTable.defaults.deferRender
10072
- *
10073
- * @example
10074
- * $(document).ready( function() {
10075
- * $('#example').dataTable( {
10076
- * "ajax": "sources/arrays.txt",
10077
- * "deferRender": true
10078
- * } );
10079
- * } );
10080
- */
10081
- "bDeferRender": false,
10082
-
10083
-
10084
- /**
10085
- * Replace a DataTable which matches the given selector and replace it with
10086
- * one which has the properties of the new initialisation object passed. If no
10087
- * table matches the selector, then the new DataTable will be constructed as
10088
- * per normal.
10089
- * @type boolean
10090
- * @default false
10091
- *
10092
- * @dtopt Options
10093
- * @name DataTable.defaults.destroy
10094
- *
10095
- * @example
10096
- * $(document).ready( function() {
10097
- * $('#example').dataTable( {
10098
- * "srollY": "200px",
10099
- * "paginate": false
10100
- * } );
10101
- *
10102
- * // Some time later....
10103
- * $('#example').dataTable( {
10104
- * "filter": false,
10105
- * "destroy": true
10106
- * } );
10107
- * } );
10108
- */
10109
- "bDestroy": false,
10110
-
10111
-
10112
- /**
10113
- * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10114
- * that it allows the end user to input multiple words (space separated) and
10115
- * will match a row containing those words, even if not in the order that was
10116
- * specified (this allow matching across multiple columns). Note that if you
10117
- * wish to use filtering in DataTables this must remain 'true' - to remove the
10118
- * default filtering input box and retain filtering abilities, please use
10119
- * {@link DataTable.defaults.dom}.
10120
- * @type boolean
10121
- * @default true
10122
- *
10123
- * @dtopt Features
10124
- * @name DataTable.defaults.searching
10125
- *
10126
- * @example
10127
- * $(document).ready( function () {
10128
- * $('#example').dataTable( {
10129
- * "searching": false
10130
- * } );
10131
- * } );
10132
- */
10133
- "bFilter": true,
10134
-
10135
-
10136
- /**
10137
- * Enable or disable the table information display. This shows information
10138
- * about the data that is currently visible on the page, including information
10139
- * about filtered data if that action is being performed.
10140
- * @type boolean
10141
- * @default true
10142
- *
10143
- * @dtopt Features
10144
- * @name DataTable.defaults.info
10145
- *
10146
- * @example
10147
- * $(document).ready( function () {
10148
- * $('#example').dataTable( {
10149
- * "info": false
10150
- * } );
10151
- * } );
10152
- */
10153
- "bInfo": true,
10154
-
10155
-
10156
- /**
10157
- * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10158
- * slightly different and additional mark-up from what DataTables has
10159
- * traditionally used).
10160
- * @type boolean
10161
- * @default false
10162
- *
10163
- * @dtopt Features
10164
- * @name DataTable.defaults.jQueryUI
10165
- *
10166
- * @example
10167
- * $(document).ready( function() {
10168
- * $('#example').dataTable( {
10169
- * "jQueryUI": true
10170
- * } );
10171
- * } );
10172
- */
10173
- "bJQueryUI": false,
10174
-
10175
-
10176
- /**
10177
- * Allows the end user to select the size of a formatted page from a select
10178
- * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10179
- * @type boolean
10180
- * @default true
10181
- *
10182
- * @dtopt Features
10183
- * @name DataTable.defaults.lengthChange
10184
- *
10185
- * @example
10186
- * $(document).ready( function () {
10187
- * $('#example').dataTable( {
10188
- * "lengthChange": false
10189
- * } );
10190
- * } );
10191
- */
10192
- "bLengthChange": true,
10193
-
10194
-
10195
- /**
10196
- * Enable or disable pagination.
10197
- * @type boolean
10198
- * @default true
10199
- *
10200
- * @dtopt Features
10201
- * @name DataTable.defaults.paging
10202
- *
10203
- * @example
10204
- * $(document).ready( function () {
10205
- * $('#example').dataTable( {
10206
- * "paging": false
10207
- * } );
10208
- * } );
10209
- */
10210
- "bPaginate": true,
10211
-
10212
-
10213
- /**
10214
- * Enable or disable the display of a 'processing' indicator when the table is
10215
- * being processed (e.g. a sort). This is particularly useful for tables with
10216
- * large amounts of data where it can take a noticeable amount of time to sort
10217
- * the entries.
10218
- * @type boolean
10219
- * @default false
10220
- *
10221
- * @dtopt Features
10222
- * @name DataTable.defaults.processing
10223
- *
10224
- * @example
10225
- * $(document).ready( function () {
10226
- * $('#example').dataTable( {
10227
- * "processing": true
10228
- * } );
10229
- * } );
10230
- */
10231
- "bProcessing": false,
10232
-
10233
-
10234
- /**
10235
- * Retrieve the DataTables object for the given selector. Note that if the
10236
- * table has already been initialised, this parameter will cause DataTables
10237
- * to simply return the object that has already been set up - it will not take
10238
- * account of any changes you might have made to the initialisation object
10239
- * passed to DataTables (setting this parameter to true is an acknowledgement
10240
- * that you understand this). `destroy` can be used to reinitialise a table if
10241
- * you need.
10242
- * @type boolean
10243
- * @default false
10244
- *
10245
- * @dtopt Options
10246
- * @name DataTable.defaults.retrieve
10247
- *
10248
- * @example
10249
- * $(document).ready( function() {
10250
- * initTable();
10251
- * tableActions();
10252
- * } );
10253
- *
10254
- * function initTable ()
10255
- * {
10256
- * return $('#example').dataTable( {
10257
- * "scrollY": "200px",
10258
- * "paginate": false,
10259
- * "retrieve": true
10260
- * } );
10261
- * }
10262
- *
10263
- * function tableActions ()
10264
- * {
10265
- * var table = initTable();
10266
- * // perform API operations with oTable
10267
- * }
10268
- */
10269
- "bRetrieve": false,
10270
-
10271
-
10272
- /**
10273
- * When vertical (y) scrolling is enabled, DataTables will force the height of
10274
- * the table's viewport to the given height at all times (useful for layout).
10275
- * However, this can look odd when filtering data down to a small data set,
10276
- * and the footer is left "floating" further down. This parameter (when
10277
- * enabled) will cause DataTables to collapse the table's viewport down when
10278
- * the result set will fit within the given Y height.
10279
- * @type boolean
10280
- * @default false
10281
- *
10282
- * @dtopt Options
10283
- * @name DataTable.defaults.scrollCollapse
10284
- *
10285
- * @example
10286
- * $(document).ready( function() {
10287
- * $('#example').dataTable( {
10288
- * "scrollY": "200",
10289
- * "scrollCollapse": true
10290
- * } );
10291
- * } );
10292
- */
10293
- "bScrollCollapse": false,
10294
-
10295
-
10296
- /**
10297
- * Configure DataTables to use server-side processing. Note that the
10298
- * `ajax` parameter must also be given in order to give DataTables a
10299
- * source to obtain the required data for each draw.
10300
- * @type boolean
10301
- * @default false
10302
- *
10303
- * @dtopt Features
10304
- * @dtopt Server-side
10305
- * @name DataTable.defaults.serverSide
10306
- *
10307
- * @example
10308
- * $(document).ready( function () {
10309
- * $('#example').dataTable( {
10310
- * "serverSide": true,
10311
- * "ajax": "xhr.php"
10312
- * } );
10313
- * } );
10314
- */
10315
- "bServerSide": false,
10316
-
10317
-
10318
- /**
10319
- * Enable or disable sorting of columns. Sorting of individual columns can be
10320
- * disabled by the `sortable` option for each column.
10321
- * @type boolean
10322
- * @default true
10323
- *
10324
- * @dtopt Features
10325
- * @name DataTable.defaults.ordering
10326
- *
10327
- * @example
10328
- * $(document).ready( function () {
10329
- * $('#example').dataTable( {
10330
- * "ordering": false
10331
- * } );
10332
- * } );
10333
- */
10334
- "bSort": true,
10335
-
10336
-
10337
- /**
10338
- * Enable or display DataTables' ability to sort multiple columns at the
10339
- * same time (activated by shift-click by the user).
10340
- * @type boolean
10341
- * @default true
10342
- *
10343
- * @dtopt Options
10344
- * @name DataTable.defaults.orderMulti
10345
- *
10346
- * @example
10347
- * // Disable multiple column sorting ability
10348
- * $(document).ready( function () {
10349
- * $('#example').dataTable( {
10350
- * "orderMulti": false
10351
- * } );
10352
- * } );
10353
- */
10354
- "bSortMulti": true,
10355
-
10356
-
10357
- /**
10358
- * Allows control over whether DataTables should use the top (true) unique
10359
- * cell that is found for a single column, or the bottom (false - default).
10360
- * This is useful when using complex headers.
10361
- * @type boolean
10362
- * @default false
10363
- *
10364
- * @dtopt Options
10365
- * @name DataTable.defaults.orderCellsTop
10366
- *
10367
- * @example
10368
- * $(document).ready( function() {
10369
- * $('#example').dataTable( {
10370
- * "orderCellsTop": true
10371
- * } );
10372
- * } );
10373
- */
10374
- "bSortCellsTop": false,
10375
-
10376
-
10377
- /**
10378
- * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10379
- * `sorting\_3` to the columns which are currently being sorted on. This is
10380
- * presented as a feature switch as it can increase processing time (while
10381
- * classes are removed and added) so for large data sets you might want to
10382
- * turn this off.
10383
- * @type boolean
10384
- * @default true
10385
- *
10386
- * @dtopt Features
10387
- * @name DataTable.defaults.orderClasses
10388
- *
10389
- * @example
10390
- * $(document).ready( function () {
10391
- * $('#example').dataTable( {
10392
- * "orderClasses": false
10393
- * } );
10394
- * } );
10395
- */
10396
- "bSortClasses": true,
10397
-
10398
-
10399
- /**
10400
- * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10401
- * used to save table display information such as pagination information,
10402
- * display length, filtering and sorting. As such when the end user reloads
10403
- * the page the display display will match what thy had previously set up.
10404
- *
10405
- * Due to the use of `localStorage` the default state saving is not supported
10406
- * in IE6 or 7. If state saving is required in those browsers, use
10407
- * `stateSaveCallback` to provide a storage solution such as cookies.
10408
- * @type boolean
10409
- * @default false
10410
- *
10411
- * @dtopt Features
10412
- * @name DataTable.defaults.stateSave
10413
- *
10414
- * @example
10415
- * $(document).ready( function () {
10416
- * $('#example').dataTable( {
10417
- * "stateSave": true
10418
- * } );
10419
- * } );
10420
- */
10421
- "bStateSave": false,
10422
-
10423
-
10424
- /**
10425
- * This function is called when a TR element is created (and all TD child
10426
- * elements have been inserted), or registered if using a DOM source, allowing
10427
- * manipulation of the TR element (adding classes etc).
10428
- * @type function
10429
- * @param {node} row "TR" element for the current row
10430
- * @param {array} data Raw data array for this row
10431
- * @param {int} dataIndex The index of this row in the internal aoData array
10432
- *
10433
- * @dtopt Callbacks
10434
- * @name DataTable.defaults.createdRow
10435
- *
10436
- * @example
10437
- * $(document).ready( function() {
10438
- * $('#example').dataTable( {
10439
- * "createdRow": function( row, data, dataIndex ) {
10440
- * // Bold the grade for all 'A' grade browsers
10441
- * if ( data[4] == "A" )
10442
- * {
10443
- * $('td:eq(4)', row).html( '<b>A</b>' );
10444
- * }
10445
- * }
10446
- * } );
10447
- * } );
10448
- */
10449
- "fnCreatedRow": null,
10450
-
10451
-
10452
- /**
10453
- * This function is called on every 'draw' event, and allows you to
10454
- * dynamically modify any aspect you want about the created DOM.
10455
- * @type function
10456
- * @param {object} settings DataTables settings object
10457
- *
10458
- * @dtopt Callbacks
10459
- * @name DataTable.defaults.drawCallback
10460
- *
10461
- * @example
10462
- * $(document).ready( function() {
10463
- * $('#example').dataTable( {
10464
- * "drawCallback": function( settings ) {
10465
- * alert( 'DataTables has redrawn the table' );
10466
- * }
10467
- * } );
10468
- * } );
10469
- */
10470
- "fnDrawCallback": null,
10471
-
10472
-
10473
- /**
10474
- * Identical to fnHeaderCallback() but for the table footer this function
10475
- * allows you to modify the table footer on every 'draw' event.
10476
- * @type function
10477
- * @param {node} foot "TR" element for the footer
10478
- * @param {array} data Full table data (as derived from the original HTML)
10479
- * @param {int} start Index for the current display starting point in the
10480
- * display array
10481
- * @param {int} end Index for the current display ending point in the
10482
- * display array
10483
- * @param {array int} display Index array to translate the visual position
10484
- * to the full data array
10485
- *
10486
- * @dtopt Callbacks
10487
- * @name DataTable.defaults.footerCallback
10488
- *
10489
- * @example
10490
- * $(document).ready( function() {
10491
- * $('#example').dataTable( {
10492
- * "footerCallback": function( tfoot, data, start, end, display ) {
10493
- * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10494
- * }
10495
- * } );
10496
- * } )
10497
- */
10498
- "fnFooterCallback": null,
10499
-
10500
-
10501
- /**
10502
- * When rendering large numbers in the information element for the table
10503
- * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10504
- * to have a comma separator for the 'thousands' units (e.g. 1 million is
10505
- * rendered as "1,000,000") to help readability for the end user. This
10506
- * function will override the default method DataTables uses.
10507
- * @type function
10508
- * @member
10509
- * @param {int} toFormat number to be formatted
10510
- * @returns {string} formatted string for DataTables to show the number
10511
- *
10512
- * @dtopt Callbacks
10513
- * @name DataTable.defaults.formatNumber
10514
- *
10515
- * @example
10516
- * // Format a number using a single quote for the separator (note that
10517
- * // this can also be done with the language.thousands option)
10518
- * $(document).ready( function() {
10519
- * $('#example').dataTable( {
10520
- * "formatNumber": function ( toFormat ) {
10521
- * return toFormat.toString().replace(
10522
- * /\B(?=(\d{3})+(?!\d))/g, "'"
10523
- * );
10524
- * };
10525
- * } );
10526
- * } );
10527
- */
10528
- "fnFormatNumber": function ( toFormat ) {
10529
- return toFormat.toString().replace(
10530
- /\B(?=(\d{3})+(?!\d))/g,
10531
- this.oLanguage.sThousands
10532
- );
10533
- },
10534
-
10535
-
10536
- /**
10537
- * This function is called on every 'draw' event, and allows you to
10538
- * dynamically modify the header row. This can be used to calculate and
10539
- * display useful information about the table.
10540
- * @type function
10541
- * @param {node} head "TR" element for the header
10542
- * @param {array} data Full table data (as derived from the original HTML)
10543
- * @param {int} start Index for the current display starting point in the
10544
- * display array
10545
- * @param {int} end Index for the current display ending point in the
10546
- * display array
10547
- * @param {array int} display Index array to translate the visual position
10548
- * to the full data array
10549
- *
10550
- * @dtopt Callbacks
10551
- * @name DataTable.defaults.headerCallback
10552
- *
10553
- * @example
10554
- * $(document).ready( function() {
10555
- * $('#example').dataTable( {
10556
- * "fheaderCallback": function( head, data, start, end, display ) {
10557
- * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10558
- * }
10559
- * } );
10560
- * } )
10561
- */
10562
- "fnHeaderCallback": null,
10563
-
10564
-
10565
- /**
10566
- * The information element can be used to convey information about the current
10567
- * state of the table. Although the internationalisation options presented by
10568
- * DataTables are quite capable of dealing with most customisations, there may
10569
- * be times where you wish to customise the string further. This callback
10570
- * allows you to do exactly that.
10571
- * @type function
10572
- * @param {object} oSettings DataTables settings object
10573
- * @param {int} start Starting position in data for the draw
10574
- * @param {int} end End position in data for the draw
10575
- * @param {int} max Total number of rows in the table (regardless of
10576
- * filtering)
10577
- * @param {int} total Total number of rows in the data set, after filtering
10578
- * @param {string} pre The string that DataTables has formatted using it's
10579
- * own rules
10580
- * @returns {string} The string to be displayed in the information element.
10581
- *
10582
- * @dtopt Callbacks
10583
- * @name DataTable.defaults.infoCallback
10584
- *
10585
- * @example
10586
- * $('#example').dataTable( {
10587
- * "infoCallback": function( settings, start, end, max, total, pre ) {
10588
- * return start +" to "+ end;
10589
- * }
10590
- * } );
10591
- */
10592
- "fnInfoCallback": null,
10593
-
10594
-
10595
- /**
10596
- * Called when the table has been initialised. Normally DataTables will
10597
- * initialise sequentially and there will be no need for this function,
10598
- * however, this does not hold true when using external language information
10599
- * since that is obtained using an async XHR call.
10600
- * @type function
10601
- * @param {object} settings DataTables settings object
10602
- * @param {object} json The JSON object request from the server - only
10603
- * present if client-side Ajax sourced data is used
10604
- *
10605
- * @dtopt Callbacks
10606
- * @name DataTable.defaults.initComplete
10607
- *
10608
- * @example
10609
- * $(document).ready( function() {
10610
- * $('#example').dataTable( {
10611
- * "initComplete": function(settings, json) {
10612
- * alert( 'DataTables has finished its initialisation.' );
10613
- * }
10614
- * } );
10615
- * } )
10616
- */
10617
- "fnInitComplete": null,
10618
-
10619
-
10620
- /**
10621
- * Called at the very start of each table draw and can be used to cancel the
10622
- * draw by returning false, any other return (including undefined) results in
10623
- * the full draw occurring).
10624
- * @type function
10625
- * @param {object} settings DataTables settings object
10626
- * @returns {boolean} False will cancel the draw, anything else (including no
10627
- * return) will allow it to complete.
10628
- *
10629
- * @dtopt Callbacks
10630
- * @name DataTable.defaults.preDrawCallback
10631
- *
10632
- * @example
10633
- * $(document).ready( function() {
10634
- * $('#example').dataTable( {
10635
- * "preDrawCallback": function( settings ) {
10636
- * if ( $('#test').val() == 1 ) {
10637
- * return false;
10638
- * }
10639
- * }
10640
- * } );
10641
- * } );
10642
- */
10643
- "fnPreDrawCallback": null,
10644
-
10645
-
10646
- /**
10647
- * This function allows you to 'post process' each row after it have been
10648
- * generated for each table draw, but before it is rendered on screen. This
10649
- * function might be used for setting the row class name etc.
10650
- * @type function
10651
- * @param {node} row "TR" element for the current row
10652
- * @param {array} data Raw data array for this row
10653
- * @param {int} displayIndex The display index for the current table draw
10654
- * @param {int} displayIndexFull The index of the data in the full list of
10655
- * rows (after filtering)
10656
- *
10657
- * @dtopt Callbacks
10658
- * @name DataTable.defaults.rowCallback
10659
- *
10660
- * @example
10661
- * $(document).ready( function() {
10662
- * $('#example').dataTable( {
10663
- * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10664
- * // Bold the grade for all 'A' grade browsers
10665
- * if ( data[4] == "A" ) {
10666
- * $('td:eq(4)', row).html( '<b>A</b>' );
10667
- * }
10668
- * }
10669
- * } );
10670
- * } );
10671
- */
10672
- "fnRowCallback": null,
10673
-
10674
-
10675
- /**
10676
- * __Deprecated__ The functionality provided by this parameter has now been
10677
- * superseded by that provided through `ajax`, which should be used instead.
10678
- *
10679
- * This parameter allows you to override the default function which obtains
10680
- * the data from the server so something more suitable for your application.
10681
- * For example you could use POST data, or pull information from a Gears or
10682
- * AIR database.
10683
- * @type function
10684
- * @member
10685
- * @param {string} source HTTP source to obtain the data from (`ajax`)
10686
- * @param {array} data A key/value pair object containing the data to send
10687
- * to the server
10688
- * @param {function} callback to be called on completion of the data get
10689
- * process that will draw the data on the page.
10690
- * @param {object} settings DataTables settings object
10691
- *
10692
- * @dtopt Callbacks
10693
- * @dtopt Server-side
10694
- * @name DataTable.defaults.serverData
10695
- *
10696
- * @deprecated 1.10. Please use `ajax` for this functionality now.
10697
- */
10698
- "fnServerData": null,
10699
-
10700
-
10701
- /**
10702
- * __Deprecated__ The functionality provided by this parameter has now been
10703
- * superseded by that provided through `ajax`, which should be used instead.
10704
- *
10705
- * It is often useful to send extra data to the server when making an Ajax
10706
- * request - for example custom filtering information, and this callback
10707
- * function makes it trivial to send extra information to the server. The
10708
- * passed in parameter is the data set that has been constructed by
10709
- * DataTables, and you can add to this or modify it as you require.
10710
- * @type function
10711
- * @param {array} data Data array (array of objects which are name/value
10712
- * pairs) that has been constructed by DataTables and will be sent to the
10713
- * server. In the case of Ajax sourced data with server-side processing
10714
- * this will be an empty array, for server-side processing there will be a
10715
- * significant number of parameters!
10716
- * @returns {undefined} Ensure that you modify the data array passed in,
10717
- * as this is passed by reference.
10718
- *
10719
- * @dtopt Callbacks
10720
- * @dtopt Server-side
10721
- * @name DataTable.defaults.serverParams
10722
- *
10723
- * @deprecated 1.10. Please use `ajax` for this functionality now.
10724
- */
10725
- "fnServerParams": null,
10726
-
10727
-
10728
- /**
10729
- * Load the table state. With this function you can define from where, and how, the
10730
- * state of a table is loaded. By default DataTables will load from `localStorage`
10731
- * but you might wish to use a server-side database or cookies.
10732
- * @type function
10733
- * @member
10734
- * @param {object} settings DataTables settings object
10735
- * @return {object} The DataTables state object to be loaded
10736
- *
10737
- * @dtopt Callbacks
10738
- * @name DataTable.defaults.stateLoadCallback
10739
- *
10740
- * @example
10741
- * $(document).ready( function() {
10742
- * $('#example').dataTable( {
10743
- * "stateSave": true,
10744
- * "stateLoadCallback": function (settings) {
10745
- * var o;
10746
- *
10747
- * // Send an Ajax request to the server to get the data. Note that
10748
- * // this is a synchronous request.
10749
- * $.ajax( {
10750
- * "url": "/state_load",
10751
- * "async": false,
10752
- * "dataType": "json",
10753
- * "success": function (json) {
10754
- * o = json;
10755
- * }
10756
- * } );
10757
- *
10758
- * return o;
10759
- * }
10760
- * } );
10761
- * } );
10762
- */
10763
- "fnStateLoadCallback": function ( settings ) {
10764
- try {
10765
- return JSON.parse(
10766
- (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
10767
- 'DataTables_'+settings.sInstance+'_'+location.pathname
10768
- )
10769
- );
10770
- } catch (e) {}
10771
- },
10772
-
10773
-
10774
- /**
10775
- * Callback which allows modification of the saved state prior to loading that state.
10776
- * This callback is called when the table is loading state from the stored data, but
10777
- * prior to the settings object being modified by the saved state. Note that for
10778
- * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10779
- * a plug-in.
10780
- * @type function
10781
- * @param {object} settings DataTables settings object
10782
- * @param {object} data The state object that is to be loaded
10783
- *
10784
- * @dtopt Callbacks
10785
- * @name DataTable.defaults.stateLoadParams
10786
- *
10787
- * @example
10788
- * // Remove a saved filter, so filtering is never loaded
10789
- * $(document).ready( function() {
10790
- * $('#example').dataTable( {
10791
- * "stateSave": true,
10792
- * "stateLoadParams": function (settings, data) {
10793
- * data.oSearch.sSearch = "";
10794
- * }
10795
- * } );
10796
- * } );
10797
- *
10798
- * @example
10799
- * // Disallow state loading by returning false
10800
- * $(document).ready( function() {
10801
- * $('#example').dataTable( {
10802
- * "stateSave": true,
10803
- * "stateLoadParams": function (settings, data) {
10804
- * return false;
10805
- * }
10806
- * } );
10807
- * } );
10808
- */
10809
- "fnStateLoadParams": null,
10810
-
10811
-
10812
- /**
10813
- * Callback that is called when the state has been loaded from the state saving method
10814
- * and the DataTables settings object has been modified as a result of the loaded state.
10815
- * @type function
10816
- * @param {object} settings DataTables settings object
10817
- * @param {object} data The state object that was loaded
10818
- *
10819
- * @dtopt Callbacks
10820
- * @name DataTable.defaults.stateLoaded
10821
- *
10822
- * @example
10823
- * // Show an alert with the filtering value that was saved
10824
- * $(document).ready( function() {
10825
- * $('#example').dataTable( {
10826
- * "stateSave": true,
10827
- * "stateLoaded": function (settings, data) {
10828
- * alert( 'Saved filter was: '+data.oSearch.sSearch );
10829
- * }
10830
- * } );
10831
- * } );
10832
- */
10833
- "fnStateLoaded": null,
10834
-
10835
-
10836
- /**
10837
- * Save the table state. This function allows you to define where and how the state
10838
- * information for the table is stored By default DataTables will use `localStorage`
10839
- * but you might wish to use a server-side database or cookies.
10840
- * @type function
10841
- * @member
10842
- * @param {object} settings DataTables settings object
10843
- * @param {object} data The state object to be saved
10844
- *
10845
- * @dtopt Callbacks
10846
- * @name DataTable.defaults.stateSaveCallback
10847
- *
10848
- * @example
10849
- * $(document).ready( function() {
10850
- * $('#example').dataTable( {
10851
- * "stateSave": true,
10852
- * "stateSaveCallback": function (settings, data) {
10853
- * // Send an Ajax request to the server with the state object
10854
- * $.ajax( {
10855
- * "url": "/state_save",
10856
- * "data": data,
10857
- * "dataType": "json",
10858
- * "method": "POST"
10859
- * "success": function () {}
10860
- * } );
10861
- * }
10862
- * } );
10863
- * } );
10864
- */
10865
- "fnStateSaveCallback": function ( settings, data ) {
10866
- try {
10867
- (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
10868
- 'DataTables_'+settings.sInstance+'_'+location.pathname,
10869
- JSON.stringify( data )
10870
- );
10871
- } catch (e) {}
10872
- },
10873
-
10874
-
10875
- /**
10876
- * Callback which allows modification of the state to be saved. Called when the table
10877
- * has changed state a new state save is required. This method allows modification of
10878
- * the state saving object prior to actually doing the save, including addition or
10879
- * other state properties or modification. Note that for plug-in authors, you should
10880
- * use the `stateSaveParams` event to save parameters for a plug-in.
10881
- * @type function
10882
- * @param {object} settings DataTables settings object
10883
- * @param {object} data The state object to be saved
10884
- *
10885
- * @dtopt Callbacks
10886
- * @name DataTable.defaults.stateSaveParams
10887
- *
10888
- * @example
10889
- * // Remove a saved filter, so filtering is never saved
10890
- * $(document).ready( function() {
10891
- * $('#example').dataTable( {
10892
- * "stateSave": true,
10893
- * "stateSaveParams": function (settings, data) {
10894
- * data.oSearch.sSearch = "";
10895
- * }
10896
- * } );
10897
- * } );
10898
- */
10899
- "fnStateSaveParams": null,
10900
-
10901
-
10902
- /**
10903
- * Duration for which the saved state information is considered valid. After this period
10904
- * has elapsed the state will be returned to the default.
10905
- * Value is given in seconds.
10906
- * @type int
10907
- * @default 7200 <i>(2 hours)</i>
10908
- *
10909
- * @dtopt Options
10910
- * @name DataTable.defaults.stateDuration
10911
- *
10912
- * @example
10913
- * $(document).ready( function() {
10914
- * $('#example').dataTable( {
10915
- * "stateDuration": 60*60*24; // 1 day
10916
- * } );
10917
- * } )
10918
- */
10919
- "iStateDuration": 7200,
10920
-
10921
-
10922
- /**
10923
- * When enabled DataTables will not make a request to the server for the first
10924
- * page draw - rather it will use the data already on the page (no sorting etc
10925
- * will be applied to it), thus saving on an XHR at load time. `deferLoading`
10926
- * is used to indicate that deferred loading is required, but it is also used
10927
- * to tell DataTables how many records there are in the full table (allowing
10928
- * the information element and pagination to be displayed correctly). In the case
10929
- * where a filtering is applied to the table on initial load, this can be
10930
- * indicated by giving the parameter as an array, where the first element is
10931
- * the number of records available after filtering and the second element is the
10932
- * number of records without filtering (allowing the table information element
10933
- * to be shown correctly).
10934
- * @type int | array
10935
- * @default null
10936
- *
10937
- * @dtopt Options
10938
- * @name DataTable.defaults.deferLoading
10939
- *
10940
- * @example
10941
- * // 57 records available in the table, no filtering applied
10942
- * $(document).ready( function() {
10943
- * $('#example').dataTable( {
10944
- * "serverSide": true,
10945
- * "ajax": "scripts/server_processing.php",
10946
- * "deferLoading": 57
10947
- * } );
10948
- * } );
10949
- *
10950
- * @example
10951
- * // 57 records after filtering, 100 without filtering (an initial filter applied)
10952
- * $(document).ready( function() {
10953
- * $('#example').dataTable( {
10954
- * "serverSide": true,
10955
- * "ajax": "scripts/server_processing.php",
10956
- * "deferLoading": [ 57, 100 ],
10957
- * "search": {
10958
- * "search": "my_filter"
10959
- * }
10960
- * } );
10961
- * } );
10962
- */
10963
- "iDeferLoading": null,
10964
-
10965
-
10966
- /**
10967
- * Number of rows to display on a single page when using pagination. If
10968
- * feature enabled (`lengthChange`) then the end user will be able to override
10969
- * this to a custom setting using a pop-up menu.
10970
- * @type int
10971
- * @default 10
10972
- *
10973
- * @dtopt Options
10974
- * @name DataTable.defaults.pageLength
10975
- *
10976
- * @example
10977
- * $(document).ready( function() {
10978
- * $('#example').dataTable( {
10979
- * "pageLength": 50
10980
- * } );
10981
- * } )
10982
- */
10983
- "iDisplayLength": 10,
10984
-
10985
-
10986
- /**
10987
- * Define the starting point for data display when using DataTables with
10988
- * pagination. Note that this parameter is the number of records, rather than
10989
- * the page number, so if you have 10 records per page and want to start on
10990
- * the third page, it should be "20".
10991
- * @type int
10992
- * @default 0
10993
- *
10994
- * @dtopt Options
10995
- * @name DataTable.defaults.displayStart
10996
- *
10997
- * @example
10998
- * $(document).ready( function() {
10999
- * $('#example').dataTable( {
11000
- * "displayStart": 20
11001
- * } );
11002
- * } )
11003
- */
11004
- "iDisplayStart": 0,
11005
-
11006
-
11007
- /**
11008
- * By default DataTables allows keyboard navigation of the table (sorting, paging,
11009
- * and filtering) by adding a `tabindex` attribute to the required elements. This
11010
- * allows you to tab through the controls and press the enter key to activate them.
11011
- * The tabindex is default 0, meaning that the tab follows the flow of the document.
11012
- * You can overrule this using this parameter if you wish. Use a value of -1 to
11013
- * disable built-in keyboard navigation.
11014
- * @type int
11015
- * @default 0
11016
- *
11017
- * @dtopt Options
11018
- * @name DataTable.defaults.tabIndex
11019
- *
11020
- * @example
11021
- * $(document).ready( function() {
11022
- * $('#example').dataTable( {
11023
- * "tabIndex": 1
11024
- * } );
11025
- * } );
11026
- */
11027
- "iTabIndex": 0,
11028
-
11029
-
11030
- /**
11031
- * Classes that DataTables assigns to the various components and features
11032
- * that it adds to the HTML table. This allows classes to be configured
11033
- * during initialisation in addition to through the static
11034
- * {@link DataTable.ext.oStdClasses} object).
11035
- * @namespace
11036
- * @name DataTable.defaults.classes
11037
- */
11038
- "oClasses": {},
11039
-
11040
-
11041
- /**
11042
- * All strings that DataTables uses in the user interface that it creates
11043
- * are defined in this object, allowing you to modified them individually or
11044
- * completely replace them all as required.
11045
- * @namespace
11046
- * @name DataTable.defaults.language
11047
- */
11048
- "oLanguage": {
11049
- /**
11050
- * Strings that are used for WAI-ARIA labels and controls only (these are not
11051
- * actually visible on the page, but will be read by screenreaders, and thus
11052
- * must be internationalised as well).
11053
- * @namespace
11054
- * @name DataTable.defaults.language.aria
11055
- */
11056
- "oAria": {
11057
- /**
11058
- * ARIA label that is added to the table headers when the column may be
11059
- * sorted ascending by activing the column (click or return when focused).
11060
- * Note that the column header is prefixed to this string.
11061
- * @type string
11062
- * @default : activate to sort column ascending
11063
- *
11064
- * @dtopt Language
11065
- * @name DataTable.defaults.language.aria.sortAscending
11066
- *
11067
- * @example
11068
- * $(document).ready( function() {
11069
- * $('#example').dataTable( {
11070
- * "language": {
11071
- * "aria": {
11072
- * "sortAscending": " - click/return to sort ascending"
11073
- * }
11074
- * }
11075
- * } );
11076
- * } );
11077
- */
11078
- "sSortAscending": ": activate to sort column ascending",
11079
-
11080
- /**
11081
- * ARIA label that is added to the table headers when the column may be
11082
- * sorted descending by activing the column (click or return when focused).
11083
- * Note that the column header is prefixed to this string.
11084
- * @type string
11085
- * @default : activate to sort column ascending
11086
- *
11087
- * @dtopt Language
11088
- * @name DataTable.defaults.language.aria.sortDescending
11089
- *
11090
- * @example
11091
- * $(document).ready( function() {
11092
- * $('#example').dataTable( {
11093
- * "language": {
11094
- * "aria": {
11095
- * "sortDescending": " - click/return to sort descending"
11096
- * }
11097
- * }
11098
- * } );
11099
- * } );
11100
- */
11101
- "sSortDescending": ": activate to sort column descending"
11102
- },
11103
-
11104
- /**
11105
- * Pagination string used by DataTables for the built-in pagination
11106
- * control types.
11107
- * @namespace
11108
- * @name DataTable.defaults.language.paginate
11109
- */
11110
- "oPaginate": {
11111
- /**
11112
- * Text to use when using the 'full_numbers' type of pagination for the
11113
- * button to take the user to the first page.
11114
- * @type string
11115
- * @default First
11116
- *
11117
- * @dtopt Language
11118
- * @name DataTable.defaults.language.paginate.first
11119
- *
11120
- * @example
11121
- * $(document).ready( function() {
11122
- * $('#example').dataTable( {
11123
- * "language": {
11124
- * "paginate": {
11125
- * "first": "First page"
11126
- * }
11127
- * }
11128
- * } );
11129
- * } );
11130
- */
11131
- "sFirst": "First",
11132
-
11133
-
11134
- /**
11135
- * Text to use when using the 'full_numbers' type of pagination for the
11136
- * button to take the user to the last page.
11137
- * @type string
11138
- * @default Last
11139
- *
11140
- * @dtopt Language
11141
- * @name DataTable.defaults.language.paginate.last
11142
- *
11143
- * @example
11144
- * $(document).ready( function() {
11145
- * $('#example').dataTable( {
11146
- * "language": {
11147
- * "paginate": {
11148
- * "last": "Last page"
11149
- * }
11150
- * }
11151
- * } );
11152
- * } );
11153
- */
11154
- "sLast": "Last",
11155
-
11156
-
11157
- /**
11158
- * Text to use for the 'next' pagination button (to take the user to the
11159
- * next page).
11160
- * @type string
11161
- * @default Next
11162
- *
11163
- * @dtopt Language
11164
- * @name DataTable.defaults.language.paginate.next
11165
- *
11166
- * @example
11167
- * $(document).ready( function() {
11168
- * $('#example').dataTable( {
11169
- * "language": {
11170
- * "paginate": {
11171
- * "next": "Next page"
11172
- * }
11173
- * }
11174
- * } );
11175
- * } );
11176
- */
11177
- "sNext": "Next",
11178
-
11179
-
11180
- /**
11181
- * Text to use for the 'previous' pagination button (to take the user to
11182
- * the previous page).
11183
- * @type string
11184
- * @default Previous
11185
- *
11186
- * @dtopt Language
11187
- * @name DataTable.defaults.language.paginate.previous
11188
- *
11189
- * @example
11190
- * $(document).ready( function() {
11191
- * $('#example').dataTable( {
11192
- * "language": {
11193
- * "paginate": {
11194
- * "previous": "Previous page"
11195
- * }
11196
- * }
11197
- * } );
11198
- * } );
11199
- */
11200
- "sPrevious": "Previous"
11201
- },
11202
-
11203
- /**
11204
- * This string is shown in preference to `zeroRecords` when the table is
11205
- * empty of data (regardless of filtering). Note that this is an optional
11206
- * parameter - if it is not given, the value of `zeroRecords` will be used
11207
- * instead (either the default or given value).
11208
- * @type string
11209
- * @default No data available in table
11210
- *
11211
- * @dtopt Language
11212
- * @name DataTable.defaults.language.emptyTable
11213
- *
11214
- * @example
11215
- * $(document).ready( function() {
11216
- * $('#example').dataTable( {
11217
- * "language": {
11218
- * "emptyTable": "No data available in table"
11219
- * }
11220
- * } );
11221
- * } );
11222
- */
11223
- "sEmptyTable": "No data available in table",
11224
-
11225
-
11226
- /**
11227
- * This string gives information to the end user about the information
11228
- * that is current on display on the page. The following tokens can be
11229
- * used in the string and will be dynamically replaced as the table
11230
- * display updates. This tokens can be placed anywhere in the string, or
11231
- * removed as needed by the language requires:
11232
- *
11233
- * * `\_START\_` - Display index of the first record on the current page
11234
- * * `\_END\_` - Display index of the last record on the current page
11235
- * * `\_TOTAL\_` - Number of records in the table after filtering
11236
- * * `\_MAX\_` - Number of records in the table without filtering
11237
- * * `\_PAGE\_` - Current page number
11238
- * * `\_PAGES\_` - Total number of pages of data in the table
11239
- *
11240
- * @type string
11241
- * @default Showing _START_ to _END_ of _TOTAL_ entries
11242
- *
11243
- * @dtopt Language
11244
- * @name DataTable.defaults.language.info
11245
- *
11246
- * @example
11247
- * $(document).ready( function() {
11248
- * $('#example').dataTable( {
11249
- * "language": {
11250
- * "info": "Showing page _PAGE_ of _PAGES_"
11251
- * }
11252
- * } );
11253
- * } );
11254
- */
11255
- "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11256
-
11257
-
11258
- /**
11259
- * Display information string for when the table is empty. Typically the
11260
- * format of this string should match `info`.
11261
- * @type string
11262
- * @default Showing 0 to 0 of 0 entries
11263
- *
11264
- * @dtopt Language
11265
- * @name DataTable.defaults.language.infoEmpty
11266
- *
11267
- * @example
11268
- * $(document).ready( function() {
11269
- * $('#example').dataTable( {
11270
- * "language": {
11271
- * "infoEmpty": "No entries to show"
11272
- * }
11273
- * } );
11274
- * } );
11275
- */
11276
- "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11277
-
11278
-
11279
- /**
11280
- * When a user filters the information in a table, this string is appended
11281
- * to the information (`info`) to give an idea of how strong the filtering
11282
- * is. The variable _MAX_ is dynamically updated.
11283
- * @type string
11284
- * @default (filtered from _MAX_ total entries)
11285
- *
11286
- * @dtopt Language
11287
- * @name DataTable.defaults.language.infoFiltered
11288
- *
11289
- * @example
11290
- * $(document).ready( function() {
11291
- * $('#example').dataTable( {
11292
- * "language": {
11293
- * "infoFiltered": " - filtering from _MAX_ records"
11294
- * }
11295
- * } );
11296
- * } );
11297
- */
11298
- "sInfoFiltered": "(filtered from _MAX_ total entries)",
11299
-
11300
-
11301
- /**
11302
- * If can be useful to append extra information to the info string at times,
11303
- * and this variable does exactly that. This information will be appended to
11304
- * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11305
- * being used) at all times.
11306
- * @type string
11307
- * @default <i>Empty string</i>
11308
- *
11309
- * @dtopt Language
11310
- * @name DataTable.defaults.language.infoPostFix
11311
- *
11312
- * @example
11313
- * $(document).ready( function() {
11314
- * $('#example').dataTable( {
11315
- * "language": {
11316
- * "infoPostFix": "All records shown are derived from real information."
11317
- * }
11318
- * } );
11319
- * } );
11320
- */
11321
- "sInfoPostFix": "",
11322
-
11323
-
11324
- /**
11325
- * This decimal place operator is a little different from the other
11326
- * language options since DataTables doesn't output floating point
11327
- * numbers, so it won't ever use this for display of a number. Rather,
11328
- * what this parameter does is modify the sort methods of the table so
11329
- * that numbers which are in a format which has a character other than
11330
- * a period (`.`) as a decimal place will be sorted numerically.
11331
- *
11332
- * Note that numbers with different decimal places cannot be shown in
11333
- * the same table and still be sortable, the table must be consistent.
11334
- * However, multiple different tables on the page can use different
11335
- * decimal place characters.
11336
- * @type string
11337
- * @default
11338
- *
11339
- * @dtopt Language
11340
- * @name DataTable.defaults.language.decimal
11341
- *
11342
- * @example
11343
- * $(document).ready( function() {
11344
- * $('#example').dataTable( {
11345
- * "language": {
11346
- * "decimal": ","
11347
- * "thousands": "."
11348
- * }
11349
- * } );
11350
- * } );
11351
- */
11352
- "sDecimal": "",
11353
-
11354
-
11355
- /**
11356
- * DataTables has a build in number formatter (`formatNumber`) which is
11357
- * used to format large numbers that are used in the table information.
11358
- * By default a comma is used, but this can be trivially changed to any
11359
- * character you wish with this parameter.
11360
- * @type string
11361
- * @default ,
11362
- *
11363
- * @dtopt Language
11364
- * @name DataTable.defaults.language.thousands
11365
- *
11366
- * @example
11367
- * $(document).ready( function() {
11368
- * $('#example').dataTable( {
11369
- * "language": {
11370
- * "thousands": "'"
11371
- * }
11372
- * } );
11373
- * } );
11374
- */
11375
- "sThousands": ",",
11376
-
11377
-
11378
- /**
11379
- * Detail the action that will be taken when the drop down menu for the
11380
- * pagination length option is changed. The '_MENU_' variable is replaced
11381
- * with a default select list of 10, 25, 50 and 100, and can be replaced
11382
- * with a custom select box if required.
11383
- * @type string
11384
- * @default Show _MENU_ entries
11385
- *
11386
- * @dtopt Language
11387
- * @name DataTable.defaults.language.lengthMenu
11388
- *
11389
- * @example
11390
- * // Language change only
11391
- * $(document).ready( function() {
11392
- * $('#example').dataTable( {
11393
- * "language": {
11394
- * "lengthMenu": "Display _MENU_ records"
11395
- * }
11396
- * } );
11397
- * } );
11398
- *
11399
- * @example
11400
- * // Language and options change
11401
- * $(document).ready( function() {
11402
- * $('#example').dataTable( {
11403
- * "language": {
11404
- * "lengthMenu": 'Display <select>'+
11405
- * '<option value="10">10</option>'+
11406
- * '<option value="20">20</option>'+
11407
- * '<option value="30">30</option>'+
11408
- * '<option value="40">40</option>'+
11409
- * '<option value="50">50</option>'+
11410
- * '<option value="-1">All</option>'+
11411
- * '</select> records'
11412
- * }
11413
- * } );
11414
- * } );
11415
- */
11416
- "sLengthMenu": "Show _MENU_ entries",
11417
-
11418
-
11419
- /**
11420
- * When using Ajax sourced data and during the first draw when DataTables is
11421
- * gathering the data, this message is shown in an empty row in the table to
11422
- * indicate to the end user the the data is being loaded. Note that this
11423
- * parameter is not used when loading data by server-side processing, just
11424
- * Ajax sourced data with client-side processing.
11425
- * @type string
11426
- * @default Loading...
11427
- *
11428
- * @dtopt Language
11429
- * @name DataTable.defaults.language.loadingRecords
11430
- *
11431
- * @example
11432
- * $(document).ready( function() {
11433
- * $('#example').dataTable( {
11434
- * "language": {
11435
- * "loadingRecords": "Please wait - loading..."
11436
- * }
11437
- * } );
11438
- * } );
11439
- */
11440
- "sLoadingRecords": "Loading...",
11441
-
11442
-
11443
- /**
11444
- * Text which is displayed when the table is processing a user action
11445
- * (usually a sort command or similar).
11446
- * @type string
11447
- * @default Processing...
11448
- *
11449
- * @dtopt Language
11450
- * @name DataTable.defaults.language.processing
11451
- *
11452
- * @example
11453
- * $(document).ready( function() {
11454
- * $('#example').dataTable( {
11455
- * "language": {
11456
- * "processing": "DataTables is currently busy"
11457
- * }
11458
- * } );
11459
- * } );
11460
- */
11461
- "sProcessing": "Processing...",
11462
-
11463
-
11464
- /**
11465
- * Details the actions that will be taken when the user types into the
11466
- * filtering input text box. The variable "_INPUT_", if used in the string,
11467
- * is replaced with the HTML text box for the filtering input allowing
11468
- * control over where it appears in the string. If "_INPUT_" is not given
11469
- * then the input box is appended to the string automatically.
11470
- * @type string
11471
- * @default Search:
11472
- *
11473
- * @dtopt Language
11474
- * @name DataTable.defaults.language.search
11475
- *
11476
- * @example
11477
- * // Input text box will be appended at the end automatically
11478
- * $(document).ready( function() {
11479
- * $('#example').dataTable( {
11480
- * "language": {
11481
- * "search": "Filter records:"
11482
- * }
11483
- * } );
11484
- * } );
11485
- *
11486
- * @example
11487
- * // Specify where the filter should appear
11488
- * $(document).ready( function() {
11489
- * $('#example').dataTable( {
11490
- * "language": {
11491
- * "search": "Apply filter _INPUT_ to table"
11492
- * }
11493
- * } );
11494
- * } );
11495
- */
11496
- "sSearch": "Search:",
11497
-
11498
-
11499
- /**
11500
- * Assign a `placeholder` attribute to the search `input` element
11501
- * @type string
11502
- * @default
11503
- *
11504
- * @dtopt Language
11505
- * @name DataTable.defaults.language.searchPlaceholder
11506
- */
11507
- "sSearchPlaceholder": "",
11508
-
11509
-
11510
- /**
11511
- * All of the language information can be stored in a file on the
11512
- * server-side, which DataTables will look up if this parameter is passed.
11513
- * It must store the URL of the language file, which is in a JSON format,
11514
- * and the object has the same properties as the oLanguage object in the
11515
- * initialiser object (i.e. the above parameters). Please refer to one of
11516
- * the example language files to see how this works in action.
11517
- * @type string
11518
- * @default <i>Empty string - i.e. disabled</i>
11519
- *
11520
- * @dtopt Language
11521
- * @name DataTable.defaults.language.url
11522
- *
11523
- * @example
11524
- * $(document).ready( function() {
11525
- * $('#example').dataTable( {
11526
- * "language": {
11527
- * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11528
- * }
11529
- * } );
11530
- * } );
11531
- */
11532
- "sUrl": "",
11533
-
11534
-
11535
- /**
11536
- * Text shown inside the table records when the is no information to be
11537
- * displayed after filtering. `emptyTable` is shown when there is simply no
11538
- * information in the table at all (regardless of filtering).
11539
- * @type string
11540
- * @default No matching records found
11541
- *
11542
- * @dtopt Language
11543
- * @name DataTable.defaults.language.zeroRecords
11544
- *
11545
- * @example
11546
- * $(document).ready( function() {
11547
- * $('#example').dataTable( {
11548
- * "language": {
11549
- * "zeroRecords": "No records to display"
11550
- * }
11551
- * } );
11552
- * } );
11553
- */
11554
- "sZeroRecords": "No matching records found"
11555
- },
11556
-
11557
-
11558
- /**
11559
- * This parameter allows you to have define the global filtering state at
11560
- * initialisation time. As an object the `search` parameter must be
11561
- * defined, but all other parameters are optional. When `regex` is true,
11562
- * the search string will be treated as a regular expression, when false
11563
- * (default) it will be treated as a straight string. When `smart`
11564
- * DataTables will use it's smart filtering methods (to word match at
11565
- * any point in the data), when false this will not be done.
11566
- * @namespace
11567
- * @extends DataTable.models.oSearch
11568
- *
11569
- * @dtopt Options
11570
- * @name DataTable.defaults.search
11571
- *
11572
- * @example
11573
- * $(document).ready( function() {
11574
- * $('#example').dataTable( {
11575
- * "search": {"search": "Initial search"}
11576
- * } );
11577
- * } )
11578
- */
11579
- "oSearch": $.extend( {}, DataTable.models.oSearch ),
11580
-
11581
-
11582
- /**
11583
- * __Deprecated__ The functionality provided by this parameter has now been
11584
- * superseded by that provided through `ajax`, which should be used instead.
11585
- *
11586
- * By default DataTables will look for the property `data` (or `aaData` for
11587
- * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11588
- * source or for server-side processing - this parameter allows that
11589
- * property to be changed. You can use Javascript dotted object notation to
11590
- * get a data source for multiple levels of nesting.
11591
- * @type string
11592
- * @default data
11593
- *
11594
- * @dtopt Options
11595
- * @dtopt Server-side
11596
- * @name DataTable.defaults.ajaxDataProp
11597
- *
11598
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11599
- */
11600
- "sAjaxDataProp": "data",
11601
-
11602
-
11603
- /**
11604
- * __Deprecated__ The functionality provided by this parameter has now been
11605
- * superseded by that provided through `ajax`, which should be used instead.
11606
- *
11607
- * You can instruct DataTables to load data from an external
11608
- * source using this parameter (use aData if you want to pass data in you
11609
- * already have). Simply provide a url a JSON object can be obtained from.
11610
- * @type string
11611
- * @default null
11612
- *
11613
- * @dtopt Options
11614
- * @dtopt Server-side
11615
- * @name DataTable.defaults.ajaxSource
11616
- *
11617
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11618
- */
11619
- "sAjaxSource": null,
11620
-
11621
-
11622
- /**
11623
- * This initialisation variable allows you to specify exactly where in the
11624
- * DOM you want DataTables to inject the various controls it adds to the page
11625
- * (for example you might want the pagination controls at the top of the
11626
- * table). DIV elements (with or without a custom class) can also be added to
11627
- * aid styling. The follow syntax is used:
11628
- * <ul>
11629
- * <li>The following options are allowed:
11630
- * <ul>
11631
- * <li>'l' - Length changing</li>
11632
- * <li>'f' - Filtering input</li>
11633
- * <li>'t' - The table!</li>
11634
- * <li>'i' - Information</li>
11635
- * <li>'p' - Pagination</li>
11636
- * <li>'r' - pRocessing</li>
11637
- * </ul>
11638
- * </li>
11639
- * <li>The following constants are allowed:
11640
- * <ul>
11641
- * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11642
- * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11643
- * </ul>
11644
- * </li>
11645
- * <li>The following syntax is expected:
11646
- * <ul>
11647
- * <li>'&lt;' and '&gt;' - div elements</li>
11648
- * <li>'&lt;"class" and '&gt;' - div with a class</li>
11649
- * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11650
- * </ul>
11651
- * </li>
11652
- * <li>Examples:
11653
- * <ul>
11654
- * <li>'&lt;"wrapper"flipt&gt;'</li>
11655
- * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11656
- * </ul>
11657
- * </li>
11658
- * </ul>
11659
- * @type string
11660
- * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11661
- * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11662
- *
11663
- * @dtopt Options
11664
- * @name DataTable.defaults.dom
11665
- *
11666
- * @example
11667
- * $(document).ready( function() {
11668
- * $('#example').dataTable( {
11669
- * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11670
- * } );
11671
- * } );
11672
- */
11673
- "sDom": "lfrtip",
11674
-
11675
-
11676
- /**
11677
- * Search delay option. This will throttle full table searches that use the
11678
- * DataTables provided search input element (it does not effect calls to
11679
- * `dt-api search()`, providing a delay before the search is made.
11680
- * @type integer
11681
- * @default 0
11682
- *
11683
- * @dtopt Options
11684
- * @name DataTable.defaults.searchDelay
11685
- *
11686
- * @example
11687
- * $(document).ready( function() {
11688
- * $('#example').dataTable( {
11689
- * "searchDelay": 200
11690
- * } );
11691
- * } )
11692
- */
11693
- "searchDelay": null,
11694
-
11695
-
11696
- /**
11697
- * DataTables features four different built-in options for the buttons to
11698
- * display for pagination control:
11699
- *
11700
- * * `simple` - 'Previous' and 'Next' buttons only
11701
- * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11702
- * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11703
- * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
11704
- * page numbers
11705
- *
11706
- * Further methods can be added using {@link DataTable.ext.oPagination}.
11707
- * @type string
11708
- * @default simple_numbers
11709
- *
11710
- * @dtopt Options
11711
- * @name DataTable.defaults.pagingType
11712
- *
11713
- * @example
11714
- * $(document).ready( function() {
11715
- * $('#example').dataTable( {
11716
- * "pagingType": "full_numbers"
11717
- * } );
11718
- * } )
11719
- */
11720
- "sPaginationType": "simple_numbers",
11721
-
11722
-
11723
- /**
11724
- * Enable horizontal scrolling. When a table is too wide to fit into a
11725
- * certain layout, or you have a large number of columns in the table, you
11726
- * can enable x-scrolling to show the table in a viewport, which can be
11727
- * scrolled. This property can be `true` which will allow the table to
11728
- * scroll horizontally when needed, or any CSS unit, or a number (in which
11729
- * case it will be treated as a pixel measurement). Setting as simply `true`
11730
- * is recommended.
11731
- * @type boolean|string
11732
- * @default <i>blank string - i.e. disabled</i>
11733
- *
11734
- * @dtopt Features
11735
- * @name DataTable.defaults.scrollX
11736
- *
11737
- * @example
11738
- * $(document).ready( function() {
11739
- * $('#example').dataTable( {
11740
- * "scrollX": true,
11741
- * "scrollCollapse": true
11742
- * } );
11743
- * } );
11744
- */
11745
- "sScrollX": "",
11746
-
11747
-
11748
- /**
11749
- * This property can be used to force a DataTable to use more width than it
11750
- * might otherwise do when x-scrolling is enabled. For example if you have a
11751
- * table which requires to be well spaced, this parameter is useful for
11752
- * "over-sizing" the table, and thus forcing scrolling. This property can by
11753
- * any CSS unit, or a number (in which case it will be treated as a pixel
11754
- * measurement).
11755
- * @type string
11756
- * @default <i>blank string - i.e. disabled</i>
11757
- *
11758
- * @dtopt Options
11759
- * @name DataTable.defaults.scrollXInner
11760
- *
11761
- * @example
11762
- * $(document).ready( function() {
11763
- * $('#example').dataTable( {
11764
- * "scrollX": "100%",
11765
- * "scrollXInner": "110%"
11766
- * } );
11767
- * } );
11768
- */
11769
- "sScrollXInner": "",
11770
-
11771
-
11772
- /**
11773
- * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11774
- * to the given height, and enable scrolling for any data which overflows the
11775
- * current viewport. This can be used as an alternative to paging to display
11776
- * a lot of data in a small area (although paging and scrolling can both be
11777
- * enabled at the same time). This property can be any CSS unit, or a number
11778
- * (in which case it will be treated as a pixel measurement).
11779
- * @type string
11780
- * @default <i>blank string - i.e. disabled</i>
11781
- *
11782
- * @dtopt Features
11783
- * @name DataTable.defaults.scrollY
11784
- *
11785
- * @example
11786
- * $(document).ready( function() {
11787
- * $('#example').dataTable( {
11788
- * "scrollY": "200px",
11789
- * "paginate": false
11790
- * } );
11791
- * } );
11792
- */
11793
- "sScrollY": "",
11794
-
11795
-
11796
- /**
11797
- * __Deprecated__ The functionality provided by this parameter has now been
11798
- * superseded by that provided through `ajax`, which should be used instead.
11799
- *
11800
- * Set the HTTP method that is used to make the Ajax call for server-side
11801
- * processing or Ajax sourced data.
11802
- * @type string
11803
- * @default GET
11804
- *
11805
- * @dtopt Options
11806
- * @dtopt Server-side
11807
- * @name DataTable.defaults.serverMethod
11808
- *
11809
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11810
- */
11811
- "sServerMethod": "GET",
11812
-
11813
-
11814
- /**
11815
- * DataTables makes use of renderers when displaying HTML elements for
11816
- * a table. These renderers can be added or modified by plug-ins to
11817
- * generate suitable mark-up for a site. For example the Bootstrap
11818
- * integration plug-in for DataTables uses a paging button renderer to
11819
- * display pagination buttons in the mark-up required by Bootstrap.
11820
- *
11821
- * For further information about the renderers available see
11822
- * DataTable.ext.renderer
11823
- * @type string|object
11824
- * @default null
11825
- *
11826
- * @name DataTable.defaults.renderer
11827
- *
11828
- */
11829
- "renderer": null,
11830
-
11831
-
11832
- /**
11833
- * Set the data property name that DataTables should use to get a row's id
11834
- * to set as the `id` property in the node.
11835
- * @type string
11836
- * @default DT_RowId
11837
- *
11838
- * @name DataTable.defaults.rowId
11839
- */
11840
- "rowId": "DT_RowId"
11841
- };
11842
-
11843
- _fnHungarianMap( DataTable.defaults );
11844
-
11845
-
11846
-
11847
- /*
11848
- * Developer note - See note in model.defaults.js about the use of Hungarian
11849
- * notation and camel case.
11850
- */
11851
-
11852
- /**
11853
- * Column options that can be given to DataTables at initialisation time.
11854
- * @namespace
11855
- */
11856
- DataTable.defaults.column = {
11857
- /**
11858
- * Define which column(s) an order will occur on for this column. This
11859
- * allows a column's ordering to take multiple columns into account when
11860
- * doing a sort or use the data from a different column. For example first
11861
- * name / last name columns make sense to do a multi-column sort over the
11862
- * two columns.
11863
- * @type array|int
11864
- * @default null <i>Takes the value of the column index automatically</i>
11865
- *
11866
- * @name DataTable.defaults.column.orderData
11867
- * @dtopt Columns
11868
- *
11869
- * @example
11870
- * // Using `columnDefs`
11871
- * $(document).ready( function() {
11872
- * $('#example').dataTable( {
11873
- * "columnDefs": [
11874
- * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
11875
- * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
11876
- * { "orderData": 2, "targets": [ 2 ] }
11877
- * ]
11878
- * } );
11879
- * } );
11880
- *
11881
- * @example
11882
- * // Using `columns`
11883
- * $(document).ready( function() {
11884
- * $('#example').dataTable( {
11885
- * "columns": [
11886
- * { "orderData": [ 0, 1 ] },
11887
- * { "orderData": [ 1, 0 ] },
11888
- * { "orderData": 2 },
11889
- * null,
11890
- * null
11891
- * ]
11892
- * } );
11893
- * } );
11894
- */
11895
- "aDataSort": null,
11896
- "iDataSort": -1,
11897
-
11898
-
11899
- /**
11900
- * You can control the default ordering direction, and even alter the
11901
- * behaviour of the sort handler (i.e. only allow ascending ordering etc)
11902
- * using this parameter.
11903
- * @type array
11904
- * @default [ 'asc', 'desc' ]
11905
- *
11906
- * @name DataTable.defaults.column.orderSequence
11907
- * @dtopt Columns
11908
- *
11909
- * @example
11910
- * // Using `columnDefs`
11911
- * $(document).ready( function() {
11912
- * $('#example').dataTable( {
11913
- * "columnDefs": [
11914
- * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
11915
- * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
11916
- * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
11917
- * ]
11918
- * } );
11919
- * } );
11920
- *
11921
- * @example
11922
- * // Using `columns`
11923
- * $(document).ready( function() {
11924
- * $('#example').dataTable( {
11925
- * "columns": [
11926
- * null,
11927
- * { "orderSequence": [ "asc" ] },
11928
- * { "orderSequence": [ "desc", "asc", "asc" ] },
11929
- * { "orderSequence": [ "desc" ] },
11930
- * null
11931
- * ]
11932
- * } );
11933
- * } );
11934
- */
11935
- "asSorting": [ 'asc', 'desc' ],
11936
-
11937
-
11938
- /**
11939
- * Enable or disable filtering on the data in this column.
11940
- * @type boolean
11941
- * @default true
11942
- *
11943
- * @name DataTable.defaults.column.searchable
11944
- * @dtopt Columns
11945
- *
11946
- * @example
11947
- * // Using `columnDefs`
11948
- * $(document).ready( function() {
11949
- * $('#example').dataTable( {
11950
- * "columnDefs": [
11951
- * { "searchable": false, "targets": [ 0 ] }
11952
- * ] } );
11953
- * } );
11954
- *
11955
- * @example
11956
- * // Using `columns`
11957
- * $(document).ready( function() {
11958
- * $('#example').dataTable( {
11959
- * "columns": [
11960
- * { "searchable": false },
11961
- * null,
11962
- * null,
11963
- * null,
11964
- * null
11965
- * ] } );
11966
- * } );
11967
- */
11968
- "bSearchable": true,
11969
-
11970
-
11971
- /**
11972
- * Enable or disable ordering on this column.
11973
- * @type boolean
11974
- * @default true
11975
- *
11976
- * @name DataTable.defaults.column.orderable
11977
- * @dtopt Columns
11978
- *
11979
- * @example
11980
- * // Using `columnDefs`
11981
- * $(document).ready( function() {
11982
- * $('#example').dataTable( {
11983
- * "columnDefs": [
11984
- * { "orderable": false, "targets": [ 0 ] }
11985
- * ] } );
11986
- * } );
11987
- *
11988
- * @example
11989
- * // Using `columns`
11990
- * $(document).ready( function() {
11991
- * $('#example').dataTable( {
11992
- * "columns": [
11993
- * { "orderable": false },
11994
- * null,
11995
- * null,
11996
- * null,
11997
- * null
11998
- * ] } );
11999
- * } );
12000
- */
12001
- "bSortable": true,
12002
-
12003
-
12004
- /**
12005
- * Enable or disable the display of this column.
12006
- * @type boolean
12007
- * @default true
12008
- *
12009
- * @name DataTable.defaults.column.visible
12010
- * @dtopt Columns
12011
- *
12012
- * @example
12013
- * // Using `columnDefs`
12014
- * $(document).ready( function() {
12015
- * $('#example').dataTable( {
12016
- * "columnDefs": [
12017
- * { "visible": false, "targets": [ 0 ] }
12018
- * ] } );
12019
- * } );
12020
- *
12021
- * @example
12022
- * // Using `columns`
12023
- * $(document).ready( function() {
12024
- * $('#example').dataTable( {
12025
- * "columns": [
12026
- * { "visible": false },
12027
- * null,
12028
- * null,
12029
- * null,
12030
- * null
12031
- * ] } );
12032
- * } );
12033
- */
12034
- "bVisible": true,
12035
-
12036
-
12037
- /**
12038
- * Developer definable function that is called whenever a cell is created (Ajax source,
12039
- * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12040
- * allowing you to modify the DOM element (add background colour for example) when the
12041
- * element is available.
12042
- * @type function
12043
- * @param {element} td The TD node that has been created
12044
- * @param {*} cellData The Data for the cell
12045
- * @param {array|object} rowData The data for the whole row
12046
- * @param {int} row The row index for the aoData data store
12047
- * @param {int} col The column index for aoColumns
12048
- *
12049
- * @name DataTable.defaults.column.createdCell
12050
- * @dtopt Columns
12051
- *
12052
- * @example
12053
- * $(document).ready( function() {
12054
- * $('#example').dataTable( {
12055
- * "columnDefs": [ {
12056
- * "targets": [3],
12057
- * "createdCell": function (td, cellData, rowData, row, col) {
12058
- * if ( cellData == "1.7" ) {
12059
- * $(td).css('color', 'blue')
12060
- * }
12061
- * }
12062
- * } ]
12063
- * });
12064
- * } );
12065
- */
12066
- "fnCreatedCell": null,
12067
-
12068
-
12069
- /**
12070
- * This parameter has been replaced by `data` in DataTables to ensure naming
12071
- * consistency. `dataProp` can still be used, as there is backwards
12072
- * compatibility in DataTables for this option, but it is strongly
12073
- * recommended that you use `data` in preference to `dataProp`.
12074
- * @name DataTable.defaults.column.dataProp
12075
- */
12076
-
12077
-
12078
- /**
12079
- * This property can be used to read data from any data source property,
12080
- * including deeply nested objects / properties. `data` can be given in a
12081
- * number of different ways which effect its behaviour:
12082
- *
12083
- * * `integer` - treated as an array index for the data source. This is the
12084
- * default that DataTables uses (incrementally increased for each column).
12085
- * * `string` - read an object property from the data source. There are
12086
- * three 'special' options that can be used in the string to alter how
12087
- * DataTables reads the data from the source object:
12088
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
12089
- * Javascript to read from nested objects, so to can the options
12090
- * specified in `data`. For example: `browser.version` or
12091
- * `browser.name`. If your object parameter name contains a period, use
12092
- * `\\` to escape it - i.e. `first\\.name`.
12093
- * * `[]` - Array notation. DataTables can automatically combine data
12094
- * from and array source, joining the data with the characters provided
12095
- * between the two brackets. For example: `name[, ]` would provide a
12096
- * comma-space separated list from the source array. If no characters
12097
- * are provided between the brackets, the original array source is
12098
- * returned.
12099
- * * `()` - Function notation. Adding `()` to the end of a parameter will
12100
- * execute a function of the name given. For example: `browser()` for a
12101
- * simple function on the data source, `browser.version()` for a
12102
- * function in a nested property or even `browser().version` to get an
12103
- * object property if the function called returns an object. Note that
12104
- * function notation is recommended for use in `render` rather than
12105
- * `data` as it is much simpler to use as a renderer.
12106
- * * `null` - use the original data source for the row rather than plucking
12107
- * data directly from it. This action has effects on two other
12108
- * initialisation options:
12109
- * * `defaultContent` - When null is given as the `data` option and
12110
- * `defaultContent` is specified for the column, the value defined by
12111
- * `defaultContent` will be used for the cell.
12112
- * * `render` - When null is used for the `data` option and the `render`
12113
- * option is specified for the column, the whole data source for the
12114
- * row is used for the renderer.
12115
- * * `function` - the function given will be executed whenever DataTables
12116
- * needs to set or get the data for a cell in the column. The function
12117
- * takes three parameters:
12118
- * * Parameters:
12119
- * * `{array|object}` The data source for the row
12120
- * * `{string}` The type call data requested - this will be 'set' when
12121
- * setting data or 'filter', 'display', 'type', 'sort' or undefined
12122
- * when gathering data. Note that when `undefined` is given for the
12123
- * type DataTables expects to get the raw data for the object back<
12124
- * * `{*}` Data to set when the second parameter is 'set'.
12125
- * * Return:
12126
- * * The return value from the function is not required when 'set' is
12127
- * the type of call, but otherwise the return is what will be used
12128
- * for the data requested.
12129
- *
12130
- * Note that `data` is a getter and setter option. If you just require
12131
- * formatting of data for output, you will likely want to use `render` which
12132
- * is simply a getter and thus simpler to use.
12133
- *
12134
- * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12135
- * name change reflects the flexibility of this property and is consistent
12136
- * with the naming of mRender. If 'mDataProp' is given, then it will still
12137
- * be used by DataTables, as it automatically maps the old name to the new
12138
- * if required.
12139
- *
12140
- * @type string|int|function|null
12141
- * @default null <i>Use automatically calculated column index</i>
12142
- *
12143
- * @name DataTable.defaults.column.data
12144
- * @dtopt Columns
12145
- *
12146
- * @example
12147
- * // Read table data from objects
12148
- * // JSON structure for each row:
12149
- * // {
12150
- * // "engine": {value},
12151
- * // "browser": {value},
12152
- * // "platform": {value},
12153
- * // "version": {value},
12154
- * // "grade": {value}
12155
- * // }
12156
- * $(document).ready( function() {
12157
- * $('#example').dataTable( {
12158
- * "ajaxSource": "sources/objects.txt",
12159
- * "columns": [
12160
- * { "data": "engine" },
12161
- * { "data": "browser" },
12162
- * { "data": "platform" },
12163
- * { "data": "version" },
12164
- * { "data": "grade" }
12165
- * ]
12166
- * } );
12167
- * } );
12168
- *
12169
- * @example
12170
- * // Read information from deeply nested objects
12171
- * // JSON structure for each row:
12172
- * // {
12173
- * // "engine": {value},
12174
- * // "browser": {value},
12175
- * // "platform": {
12176
- * // "inner": {value}
12177
- * // },
12178
- * // "details": [
12179
- * // {value}, {value}
12180
- * // ]
12181
- * // }
12182
- * $(document).ready( function() {
12183
- * $('#example').dataTable( {
12184
- * "ajaxSource": "sources/deep.txt",
12185
- * "columns": [
12186
- * { "data": "engine" },
12187
- * { "data": "browser" },
12188
- * { "data": "platform.inner" },
12189
- * { "data": "platform.details.0" },
12190
- * { "data": "platform.details.1" }
12191
- * ]
12192
- * } );
12193
- * } );
12194
- *
12195
- * @example
12196
- * // Using `data` as a function to provide different information for
12197
- * // sorting, filtering and display. In this case, currency (price)
12198
- * $(document).ready( function() {
12199
- * $('#example').dataTable( {
12200
- * "columnDefs": [ {
12201
- * "targets": [ 0 ],
12202
- * "data": function ( source, type, val ) {
12203
- * if (type === 'set') {
12204
- * source.price = val;
12205
- * // Store the computed dislay and filter values for efficiency
12206
- * source.price_display = val=="" ? "" : "$"+numberFormat(val);
12207
- * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12208
- * return;
12209
- * }
12210
- * else if (type === 'display') {
12211
- * return source.price_display;
12212
- * }
12213
- * else if (type === 'filter') {
12214
- * return source.price_filter;
12215
- * }
12216
- * // 'sort', 'type' and undefined all just use the integer
12217
- * return source.price;
12218
- * }
12219
- * } ]
12220
- * } );
12221
- * } );
12222
- *
12223
- * @example
12224
- * // Using default content
12225
- * $(document).ready( function() {
12226
- * $('#example').dataTable( {
12227
- * "columnDefs": [ {
12228
- * "targets": [ 0 ],
12229
- * "data": null,
12230
- * "defaultContent": "Click to edit"
12231
- * } ]
12232
- * } );
12233
- * } );
12234
- *
12235
- * @example
12236
- * // Using array notation - outputting a list from an array
12237
- * $(document).ready( function() {
12238
- * $('#example').dataTable( {
12239
- * "columnDefs": [ {
12240
- * "targets": [ 0 ],
12241
- * "data": "name[, ]"
12242
- * } ]
12243
- * } );
12244
- * } );
12245
- *
12246
- */
12247
- "mData": null,
12248
-
12249
-
12250
- /**
12251
- * This property is the rendering partner to `data` and it is suggested that
12252
- * when you want to manipulate data for display (including filtering,
12253
- * sorting etc) without altering the underlying data for the table, use this
12254
- * property. `render` can be considered to be the the read only companion to
12255
- * `data` which is read / write (then as such more complex). Like `data`
12256
- * this option can be given in a number of different ways to effect its
12257
- * behaviour:
12258
- *
12259
- * * `integer` - treated as an array index for the data source. This is the
12260
- * default that DataTables uses (incrementally increased for each column).
12261
- * * `string` - read an object property from the data source. There are
12262
- * three 'special' options that can be used in the string to alter how
12263
- * DataTables reads the data from the source object:
12264
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
12265
- * Javascript to read from nested objects, so to can the options
12266
- * specified in `data`. For example: `browser.version` or
12267
- * `browser.name`. If your object parameter name contains a period, use
12268
- * `\\` to escape it - i.e. `first\\.name`.
12269
- * * `[]` - Array notation. DataTables can automatically combine data
12270
- * from and array source, joining the data with the characters provided
12271
- * between the two brackets. For example: `name[, ]` would provide a
12272
- * comma-space separated list from the source array. If no characters
12273
- * are provided between the brackets, the original array source is
12274
- * returned.
12275
- * * `()` - Function notation. Adding `()` to the end of a parameter will
12276
- * execute a function of the name given. For example: `browser()` for a
12277
- * simple function on the data source, `browser.version()` for a
12278
- * function in a nested property or even `browser().version` to get an
12279
- * object property if the function called returns an object.
12280
- * * `object` - use different data for the different data types requested by
12281
- * DataTables ('filter', 'display', 'type' or 'sort'). The property names
12282
- * of the object is the data type the property refers to and the value can
12283
- * defined using an integer, string or function using the same rules as
12284
- * `render` normally does. Note that an `_` option _must_ be specified.
12285
- * This is the default value to use if you haven't specified a value for
12286
- * the data type requested by DataTables.
12287
- * * `function` - the function given will be executed whenever DataTables
12288
- * needs to set or get the data for a cell in the column. The function
12289
- * takes three parameters:
12290
- * * Parameters:
12291
- * * {array|object} The data source for the row (based on `data`)
12292
- * * {string} The type call data requested - this will be 'filter',
12293
- * 'display', 'type' or 'sort'.
12294
- * * {array|object} The full data source for the row (not based on
12295
- * `data`)
12296
- * * Return:
12297
- * * The return value from the function is what will be used for the
12298
- * data requested.
12299
- *
12300
- * @type string|int|function|object|null
12301
- * @default null Use the data source value.
12302
- *
12303
- * @name DataTable.defaults.column.render
12304
- * @dtopt Columns
12305
- *
12306
- * @example
12307
- * // Create a comma separated list from an array of objects
12308
- * $(document).ready( function() {
12309
- * $('#example').dataTable( {
12310
- * "ajaxSource": "sources/deep.txt",
12311
- * "columns": [
12312
- * { "data": "engine" },
12313
- * { "data": "browser" },
12314
- * {
12315
- * "data": "platform",
12316
- * "render": "[, ].name"
12317
- * }
12318
- * ]
12319
- * } );
12320
- * } );
12321
- *
12322
- * @example
12323
- * // Execute a function to obtain data
12324
- * $(document).ready( function() {
12325
- * $('#example').dataTable( {
12326
- * "columnDefs": [ {
12327
- * "targets": [ 0 ],
12328
- * "data": null, // Use the full data source object for the renderer's source
12329
- * "render": "browserName()"
12330
- * } ]
12331
- * } );
12332
- * } );
12333
- *
12334
- * @example
12335
- * // As an object, extracting different data for the different types
12336
- * // This would be used with a data source such as:
12337
- * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12338
- * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12339
- * // (which has both forms) is used for filtering for if a user inputs either format, while
12340
- * // the formatted phone number is the one that is shown in the table.
12341
- * $(document).ready( function() {
12342
- * $('#example').dataTable( {
12343
- * "columnDefs": [ {
12344
- * "targets": [ 0 ],
12345
- * "data": null, // Use the full data source object for the renderer's source
12346
- * "render": {
12347
- * "_": "phone",
12348
- * "filter": "phone_filter",
12349
- * "display": "phone_display"
12350
- * }
12351
- * } ]
12352
- * } );
12353
- * } );
12354
- *
12355
- * @example
12356
- * // Use as a function to create a link from the data source
12357
- * $(document).ready( function() {
12358
- * $('#example').dataTable( {
12359
- * "columnDefs": [ {
12360
- * "targets": [ 0 ],
12361
- * "data": "download_link",
12362
- * "render": function ( data, type, full ) {
12363
- * return '<a href="'+data+'">Download</a>';
12364
- * }
12365
- * } ]
12366
- * } );
12367
- * } );
12368
- */
12369
- "mRender": null,
12370
-
12371
-
12372
- /**
12373
- * Change the cell type created for the column - either TD cells or TH cells. This
12374
- * can be useful as TH cells have semantic meaning in the table body, allowing them
12375
- * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12376
- * @type string
12377
- * @default td
12378
- *
12379
- * @name DataTable.defaults.column.cellType
12380
- * @dtopt Columns
12381
- *
12382
- * @example
12383
- * // Make the first column use TH cells
12384
- * $(document).ready( function() {
12385
- * $('#example').dataTable( {
12386
- * "columnDefs": [ {
12387
- * "targets": [ 0 ],
12388
- * "cellType": "th"
12389
- * } ]
12390
- * } );
12391
- * } );
12392
- */
12393
- "sCellType": "td",
12394
-
12395
-
12396
- /**
12397
- * Class to give to each cell in this column.
12398
- * @type string
12399
- * @default <i>Empty string</i>
12400
- *
12401
- * @name DataTable.defaults.column.class
12402
- * @dtopt Columns
12403
- *
12404
- * @example
12405
- * // Using `columnDefs`
12406
- * $(document).ready( function() {
12407
- * $('#example').dataTable( {
12408
- * "columnDefs": [
12409
- * { "class": "my_class", "targets": [ 0 ] }
12410
- * ]
12411
- * } );
12412
- * } );
12413
- *
12414
- * @example
12415
- * // Using `columns`
12416
- * $(document).ready( function() {
12417
- * $('#example').dataTable( {
12418
- * "columns": [
12419
- * { "class": "my_class" },
12420
- * null,
12421
- * null,
12422
- * null,
12423
- * null
12424
- * ]
12425
- * } );
12426
- * } );
12427
- */
12428
- "sClass": "",
12429
-
12430
- /**
12431
- * When DataTables calculates the column widths to assign to each column,
12432
- * it finds the longest string in each column and then constructs a
12433
- * temporary table and reads the widths from that. The problem with this
12434
- * is that "mmm" is much wider then "iiii", but the latter is a longer
12435
- * string - thus the calculation can go wrong (doing it properly and putting
12436
- * it into an DOM object and measuring that is horribly(!) slow). Thus as
12437
- * a "work around" we provide this option. It will append its value to the
12438
- * text that is found to be the longest string for the column - i.e. padding.
12439
- * Generally you shouldn't need this!
12440
- * @type string
12441
- * @default <i>Empty string<i>
12442
- *
12443
- * @name DataTable.defaults.column.contentPadding
12444
- * @dtopt Columns
12445
- *
12446
- * @example
12447
- * // Using `columns`
12448
- * $(document).ready( function() {
12449
- * $('#example').dataTable( {
12450
- * "columns": [
12451
- * null,
12452
- * null,
12453
- * null,
12454
- * {
12455
- * "contentPadding": "mmm"
12456
- * }
12457
- * ]
12458
- * } );
12459
- * } );
12460
- */
12461
- "sContentPadding": "",
12462
-
12463
-
12464
- /**
12465
- * Allows a default value to be given for a column's data, and will be used
12466
- * whenever a null data source is encountered (this can be because `data`
12467
- * is set to null, or because the data source itself is null).
12468
- * @type string
12469
- * @default null
12470
- *
12471
- * @name DataTable.defaults.column.defaultContent
12472
- * @dtopt Columns
12473
- *
12474
- * @example
12475
- * // Using `columnDefs`
12476
- * $(document).ready( function() {
12477
- * $('#example').dataTable( {
12478
- * "columnDefs": [
12479
- * {
12480
- * "data": null,
12481
- * "defaultContent": "Edit",
12482
- * "targets": [ -1 ]
12483
- * }
12484
- * ]
12485
- * } );
12486
- * } );
12487
- *
12488
- * @example
12489
- * // Using `columns`
12490
- * $(document).ready( function() {
12491
- * $('#example').dataTable( {
12492
- * "columns": [
12493
- * null,
12494
- * null,
12495
- * null,
12496
- * {
12497
- * "data": null,
12498
- * "defaultContent": "Edit"
12499
- * }
12500
- * ]
12501
- * } );
12502
- * } );
12503
- */
12504
- "sDefaultContent": null,
12505
-
12506
-
12507
- /**
12508
- * This parameter is only used in DataTables' server-side processing. It can
12509
- * be exceptionally useful to know what columns are being displayed on the
12510
- * client side, and to map these to database fields. When defined, the names
12511
- * also allow DataTables to reorder information from the server if it comes
12512
- * back in an unexpected order (i.e. if you switch your columns around on the
12513
- * client-side, your server-side code does not also need updating).
12514
- * @type string
12515
- * @default <i>Empty string</i>
12516
- *
12517
- * @name DataTable.defaults.column.name
12518
- * @dtopt Columns
12519
- *
12520
- * @example
12521
- * // Using `columnDefs`
12522
- * $(document).ready( function() {
12523
- * $('#example').dataTable( {
12524
- * "columnDefs": [
12525
- * { "name": "engine", "targets": [ 0 ] },
12526
- * { "name": "browser", "targets": [ 1 ] },
12527
- * { "name": "platform", "targets": [ 2 ] },
12528
- * { "name": "version", "targets": [ 3 ] },
12529
- * { "name": "grade", "targets": [ 4 ] }
12530
- * ]
12531
- * } );
12532
- * } );
12533
- *
12534
- * @example
12535
- * // Using `columns`
12536
- * $(document).ready( function() {
12537
- * $('#example').dataTable( {
12538
- * "columns": [
12539
- * { "name": "engine" },
12540
- * { "name": "browser" },
12541
- * { "name": "platform" },
12542
- * { "name": "version" },
12543
- * { "name": "grade" }
12544
- * ]
12545
- * } );
12546
- * } );
12547
- */
12548
- "sName": "",
12549
-
12550
-
12551
- /**
12552
- * Defines a data source type for the ordering which can be used to read
12553
- * real-time information from the table (updating the internally cached
12554
- * version) prior to ordering. This allows ordering to occur on user
12555
- * editable elements such as form inputs.
12556
- * @type string
12557
- * @default std
12558
- *
12559
- * @name DataTable.defaults.column.orderDataType
12560
- * @dtopt Columns
12561
- *
12562
- * @example
12563
- * // Using `columnDefs`
12564
- * $(document).ready( function() {
12565
- * $('#example').dataTable( {
12566
- * "columnDefs": [
12567
- * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12568
- * { "type": "numeric", "targets": [ 3 ] },
12569
- * { "orderDataType": "dom-select", "targets": [ 4 ] },
12570
- * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12571
- * ]
12572
- * } );
12573
- * } );
12574
- *
12575
- * @example
12576
- * // Using `columns`
12577
- * $(document).ready( function() {
12578
- * $('#example').dataTable( {
12579
- * "columns": [
12580
- * null,
12581
- * null,
12582
- * { "orderDataType": "dom-text" },
12583
- * { "orderDataType": "dom-text", "type": "numeric" },
12584
- * { "orderDataType": "dom-select" },
12585
- * { "orderDataType": "dom-checkbox" }
12586
- * ]
12587
- * } );
12588
- * } );
12589
- */
12590
- "sSortDataType": "std",
12591
-
12592
-
12593
- /**
12594
- * The title of this column.
12595
- * @type string
12596
- * @default null <i>Derived from the 'TH' value for this column in the
12597
- * original HTML table.</i>
12598
- *
12599
- * @name DataTable.defaults.column.title
12600
- * @dtopt Columns
12601
- *
12602
- * @example
12603
- * // Using `columnDefs`
12604
- * $(document).ready( function() {
12605
- * $('#example').dataTable( {
12606
- * "columnDefs": [
12607
- * { "title": "My column title", "targets": [ 0 ] }
12608
- * ]
12609
- * } );
12610
- * } );
12611
- *
12612
- * @example
12613
- * // Using `columns`
12614
- * $(document).ready( function() {
12615
- * $('#example').dataTable( {
12616
- * "columns": [
12617
- * { "title": "My column title" },
12618
- * null,
12619
- * null,
12620
- * null,
12621
- * null
12622
- * ]
12623
- * } );
12624
- * } );
12625
- */
12626
- "sTitle": null,
12627
-
12628
-
12629
- /**
12630
- * The type allows you to specify how the data for this column will be
12631
- * ordered. Four types (string, numeric, date and html (which will strip
12632
- * HTML tags before ordering)) are currently available. Note that only date
12633
- * formats understood by Javascript's Date() object will be accepted as type
12634
- * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12635
- * 'numeric', 'date' or 'html' (by default). Further types can be adding
12636
- * through plug-ins.
12637
- * @type string
12638
- * @default null <i>Auto-detected from raw data</i>
12639
- *
12640
- * @name DataTable.defaults.column.type
12641
- * @dtopt Columns
12642
- *
12643
- * @example
12644
- * // Using `columnDefs`
12645
- * $(document).ready( function() {
12646
- * $('#example').dataTable( {
12647
- * "columnDefs": [
12648
- * { "type": "html", "targets": [ 0 ] }
12649
- * ]
12650
- * } );
12651
- * } );
12652
- *
12653
- * @example
12654
- * // Using `columns`
12655
- * $(document).ready( function() {
12656
- * $('#example').dataTable( {
12657
- * "columns": [
12658
- * { "type": "html" },
12659
- * null,
12660
- * null,
12661
- * null,
12662
- * null
12663
- * ]
12664
- * } );
12665
- * } );
12666
- */
12667
- "sType": null,
12668
-
12669
-
12670
- /**
12671
- * Defining the width of the column, this parameter may take any CSS value
12672
- * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12673
- * been given a specific width through this interface ensuring that the table
12674
- * remains readable.
12675
- * @type string
12676
- * @default null <i>Automatic</i>
12677
- *
12678
- * @name DataTable.defaults.column.width
12679
- * @dtopt Columns
12680
- *
12681
- * @example
12682
- * // Using `columnDefs`
12683
- * $(document).ready( function() {
12684
- * $('#example').dataTable( {
12685
- * "columnDefs": [
12686
- * { "width": "20%", "targets": [ 0 ] }
12687
- * ]
12688
- * } );
12689
- * } );
12690
- *
12691
- * @example
12692
- * // Using `columns`
12693
- * $(document).ready( function() {
12694
- * $('#example').dataTable( {
12695
- * "columns": [
12696
- * { "width": "20%" },
12697
- * null,
12698
- * null,
12699
- * null,
12700
- * null
12701
- * ]
12702
- * } );
12703
- * } );
12704
- */
12705
- "sWidth": null
12706
- };
12707
-
12708
- _fnHungarianMap( DataTable.defaults.column );
12709
-
12710
-
12711
-
12712
- /**
12713
- * DataTables settings object - this holds all the information needed for a
12714
- * given table, including configuration, data and current application of the
12715
- * table options. DataTables does not have a single instance for each DataTable
12716
- * with the settings attached to that instance, but rather instances of the
12717
- * DataTable "class" are created on-the-fly as needed (typically by a
12718
- * $().dataTable() call) and the settings object is then applied to that
12719
- * instance.
12720
- *
12721
- * Note that this object is related to {@link DataTable.defaults} but this
12722
- * one is the internal data store for DataTables's cache of columns. It should
12723
- * NOT be manipulated outside of DataTables. Any configuration should be done
12724
- * through the initialisation options.
12725
- * @namespace
12726
- * @todo Really should attach the settings object to individual instances so we
12727
- * don't need to create new instances on each $().dataTable() call (if the
12728
- * table already exists). It would also save passing oSettings around and
12729
- * into every single function. However, this is a very significant
12730
- * architecture change for DataTables and will almost certainly break
12731
- * backwards compatibility with older installations. This is something that
12732
- * will be done in 2.0.
12733
- */
12734
- DataTable.models.oSettings = {
12735
- /**
12736
- * Primary features of DataTables and their enablement state.
12737
- * @namespace
12738
- */
12739
- "oFeatures": {
12740
-
12741
- /**
12742
- * Flag to say if DataTables should automatically try to calculate the
12743
- * optimum table and columns widths (true) or not (false).
12744
- * Note that this parameter will be set by the initialisation routine. To
12745
- * set a default use {@link DataTable.defaults}.
12746
- * @type boolean
12747
- */
12748
- "bAutoWidth": null,
12749
-
12750
- /**
12751
- * Delay the creation of TR and TD elements until they are actually
12752
- * needed by a driven page draw. This can give a significant speed
12753
- * increase for Ajax source and Javascript source data, but makes no
12754
- * difference at all fro DOM and server-side processing tables.
12755
- * Note that this parameter will be set by the initialisation routine. To
12756
- * set a default use {@link DataTable.defaults}.
12757
- * @type boolean
12758
- */
12759
- "bDeferRender": null,
12760
-
12761
- /**
12762
- * Enable filtering on the table or not. Note that if this is disabled
12763
- * then there is no filtering at all on the table, including fnFilter.
12764
- * To just remove the filtering input use sDom and remove the 'f' option.
12765
- * Note that this parameter will be set by the initialisation routine. To
12766
- * set a default use {@link DataTable.defaults}.
12767
- * @type boolean
12768
- */
12769
- "bFilter": null,
12770
-
12771
- /**
12772
- * Table information element (the 'Showing x of y records' div) enable
12773
- * flag.
12774
- * Note that this parameter will be set by the initialisation routine. To
12775
- * set a default use {@link DataTable.defaults}.
12776
- * @type boolean
12777
- */
12778
- "bInfo": null,
12779
-
12780
- /**
12781
- * Present a user control allowing the end user to change the page size
12782
- * when pagination is enabled.
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
- "bLengthChange": null,
12788
-
12789
- /**
12790
- * Pagination enabled or not. Note that if this is disabled then length
12791
- * changing must also be disabled.
12792
- * Note that this parameter will be set by the initialisation routine. To
12793
- * set a default use {@link DataTable.defaults}.
12794
- * @type boolean
12795
- */
12796
- "bPaginate": null,
12797
-
12798
- /**
12799
- * Processing indicator enable flag whenever DataTables is enacting a
12800
- * user request - typically an Ajax request for server-side processing.
12801
- * Note that this parameter will be set by the initialisation routine. To
12802
- * set a default use {@link DataTable.defaults}.
12803
- * @type boolean
12804
- */
12805
- "bProcessing": null,
12806
-
12807
- /**
12808
- * Server-side processing enabled flag - when enabled DataTables will
12809
- * get all data from the server for every draw - there is no filtering,
12810
- * sorting or paging done on the client-side.
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
- "bServerSide": null,
12816
-
12817
- /**
12818
- * Sorting enablement flag.
12819
- * Note that this parameter will be set by the initialisation routine. To
12820
- * set a default use {@link DataTable.defaults}.
12821
- * @type boolean
12822
- */
12823
- "bSort": null,
12824
-
12825
- /**
12826
- * Multi-column sorting
12827
- * Note that this parameter will be set by the initialisation routine. To
12828
- * set a default use {@link DataTable.defaults}.
12829
- * @type boolean
12830
- */
12831
- "bSortMulti": null,
12832
-
12833
- /**
12834
- * Apply a class to the columns which are being sorted to provide a
12835
- * visual highlight or not. This can slow things down when enabled since
12836
- * there is a lot of DOM interaction.
12837
- * Note that this parameter will be set by the initialisation routine. To
12838
- * set a default use {@link DataTable.defaults}.
12839
- * @type boolean
12840
- */
12841
- "bSortClasses": null,
12842
-
12843
- /**
12844
- * State saving enablement flag.
12845
- * Note that this parameter will be set by the initialisation routine. To
12846
- * set a default use {@link DataTable.defaults}.
12847
- * @type boolean
12848
- */
12849
- "bStateSave": null
12850
- },
12851
-
12852
-
12853
- /**
12854
- * Scrolling settings for a table.
12855
- * @namespace
12856
- */
12857
- "oScroll": {
12858
- /**
12859
- * When the table is shorter in height than sScrollY, collapse the
12860
- * table container down to the height of the table (when true).
12861
- * Note that this parameter will be set by the initialisation routine. To
12862
- * set a default use {@link DataTable.defaults}.
12863
- * @type boolean
12864
- */
12865
- "bCollapse": null,
12866
-
12867
- /**
12868
- * Width of the scrollbar for the web-browser's platform. Calculated
12869
- * during table initialisation.
12870
- * @type int
12871
- * @default 0
12872
- */
12873
- "iBarWidth": 0,
12874
-
12875
- /**
12876
- * Viewport width for horizontal scrolling. Horizontal scrolling is
12877
- * disabled if an empty string.
12878
- * Note that this parameter will be set by the initialisation routine. To
12879
- * set a default use {@link DataTable.defaults}.
12880
- * @type string
12881
- */
12882
- "sX": null,
12883
-
12884
- /**
12885
- * Width to expand the table to when using x-scrolling. Typically you
12886
- * should not need to use this.
12887
- * Note that this parameter will be set by the initialisation routine. To
12888
- * set a default use {@link DataTable.defaults}.
12889
- * @type string
12890
- * @deprecated
12891
- */
12892
- "sXInner": null,
12893
-
12894
- /**
12895
- * Viewport height for vertical scrolling. Vertical scrolling is disabled
12896
- * if an empty string.
12897
- * Note that this parameter will be set by the initialisation routine. To
12898
- * set a default use {@link DataTable.defaults}.
12899
- * @type string
12900
- */
12901
- "sY": null
12902
- },
12903
-
12904
- /**
12905
- * Language information for the table.
12906
- * @namespace
12907
- * @extends DataTable.defaults.oLanguage
12908
- */
12909
- "oLanguage": {
12910
- /**
12911
- * Information callback function. See
12912
- * {@link DataTable.defaults.fnInfoCallback}
12913
- * @type function
12914
- * @default null
12915
- */
12916
- "fnInfoCallback": null
12917
- },
12918
-
12919
- /**
12920
- * Browser support parameters
12921
- * @namespace
12922
- */
12923
- "oBrowser": {
12924
- /**
12925
- * Indicate if the browser incorrectly calculates width:100% inside a
12926
- * scrolling element (IE6/7)
12927
- * @type boolean
12928
- * @default false
12929
- */
12930
- "bScrollOversize": false,
12931
-
12932
- /**
12933
- * Determine if the vertical scrollbar is on the right or left of the
12934
- * scrolling container - needed for rtl language layout, although not
12935
- * all browsers move the scrollbar (Safari).
12936
- * @type boolean
12937
- * @default false
12938
- */
12939
- "bScrollbarLeft": false,
12940
-
12941
- /**
12942
- * Flag for if `getBoundingClientRect` is fully supported or not
12943
- * @type boolean
12944
- * @default false
12945
- */
12946
- "bBounding": false
12947
- },
12948
-
12949
-
12950
- "ajax": null,
12951
-
12952
-
12953
- /**
12954
- * Array referencing the nodes which are used for the features. The
12955
- * parameters of this object match what is allowed by sDom - i.e.
12956
- * <ul>
12957
- * <li>'l' - Length changing</li>
12958
- * <li>'f' - Filtering input</li>
12959
- * <li>'t' - The table!</li>
12960
- * <li>'i' - Information</li>
12961
- * <li>'p' - Pagination</li>
12962
- * <li>'r' - pRocessing</li>
12963
- * </ul>
12964
- * @type array
12965
- * @default []
12966
- */
12967
- "aanFeatures": [],
12968
-
12969
- /**
12970
- * Store data information - see {@link DataTable.models.oRow} for detailed
12971
- * information.
12972
- * @type array
12973
- * @default []
12974
- */
12975
- "aoData": [],
12976
-
12977
- /**
12978
- * Array of indexes which are in the current display (after filtering etc)
12979
- * @type array
12980
- * @default []
12981
- */
12982
- "aiDisplay": [],
12983
-
12984
- /**
12985
- * Array of indexes for display - no filtering
12986
- * @type array
12987
- * @default []
12988
- */
12989
- "aiDisplayMaster": [],
12990
-
12991
- /**
12992
- * Map of row ids to data indexes
12993
- * @type object
12994
- * @default {}
12995
- */
12996
- "aIds": {},
12997
-
12998
- /**
12999
- * Store information about each column that is in use
13000
- * @type array
13001
- * @default []
13002
- */
13003
- "aoColumns": [],
13004
-
13005
- /**
13006
- * Store information about the table's header
13007
- * @type array
13008
- * @default []
13009
- */
13010
- "aoHeader": [],
13011
-
13012
- /**
13013
- * Store information about the table's footer
13014
- * @type array
13015
- * @default []
13016
- */
13017
- "aoFooter": [],
13018
-
13019
- /**
13020
- * Store the applied global search information in case we want to force a
13021
- * research or compare the old search to a new one.
13022
- * Note that this parameter will be set by the initialisation routine. To
13023
- * set a default use {@link DataTable.defaults}.
13024
- * @namespace
13025
- * @extends DataTable.models.oSearch
13026
- */
13027
- "oPreviousSearch": {},
13028
-
13029
- /**
13030
- * Store the applied search for each column - see
13031
- * {@link DataTable.models.oSearch} for the format that is used for the
13032
- * filtering information for each column.
13033
- * @type array
13034
- * @default []
13035
- */
13036
- "aoPreSearchCols": [],
13037
-
13038
- /**
13039
- * Sorting that is applied to the table. Note that the inner arrays are
13040
- * used in the following manner:
13041
- * <ul>
13042
- * <li>Index 0 - column number</li>
13043
- * <li>Index 1 - current sorting direction</li>
13044
- * </ul>
13045
- * Note that this parameter will be set by the initialisation routine. To
13046
- * set a default use {@link DataTable.defaults}.
13047
- * @type array
13048
- * @todo These inner arrays should really be objects
13049
- */
13050
- "aaSorting": null,
13051
-
13052
- /**
13053
- * Sorting that is always applied to the table (i.e. prefixed in front of
13054
- * aaSorting).
13055
- * Note that this parameter will be set by the initialisation routine. To
13056
- * set a default use {@link DataTable.defaults}.
13057
- * @type array
13058
- * @default []
13059
- */
13060
- "aaSortingFixed": [],
13061
-
13062
- /**
13063
- * Classes to use for the striping of a table.
13064
- * Note that this parameter will be set by the initialisation routine. To
13065
- * set a default use {@link DataTable.defaults}.
13066
- * @type array
13067
- * @default []
13068
- */
13069
- "asStripeClasses": null,
13070
-
13071
- /**
13072
- * If restoring a table - we should restore its striping classes as well
13073
- * @type array
13074
- * @default []
13075
- */
13076
- "asDestroyStripes": [],
13077
-
13078
- /**
13079
- * If restoring a table - we should restore its width
13080
- * @type int
13081
- * @default 0
13082
- */
13083
- "sDestroyWidth": 0,
13084
-
13085
- /**
13086
- * Callback functions array for every time a row is inserted (i.e. on a draw).
13087
- * @type array
13088
- * @default []
13089
- */
13090
- "aoRowCallback": [],
13091
-
13092
- /**
13093
- * Callback functions for the header on each draw.
13094
- * @type array
13095
- * @default []
13096
- */
13097
- "aoHeaderCallback": [],
13098
-
13099
- /**
13100
- * Callback function for the footer on each draw.
13101
- * @type array
13102
- * @default []
13103
- */
13104
- "aoFooterCallback": [],
13105
-
13106
- /**
13107
- * Array of callback functions for draw callback functions
13108
- * @type array
13109
- * @default []
13110
- */
13111
- "aoDrawCallback": [],
13112
-
13113
- /**
13114
- * Array of callback functions for row created function
13115
- * @type array
13116
- * @default []
13117
- */
13118
- "aoRowCreatedCallback": [],
13119
-
13120
- /**
13121
- * Callback functions for just before the table is redrawn. A return of
13122
- * false will be used to cancel the draw.
13123
- * @type array
13124
- * @default []
13125
- */
13126
- "aoPreDrawCallback": [],
13127
-
13128
- /**
13129
- * Callback functions for when the table has been initialised.
13130
- * @type array
13131
- * @default []
13132
- */
13133
- "aoInitComplete": [],
13134
-
13135
-
13136
- /**
13137
- * Callbacks for modifying the settings to be stored for state saving, prior to
13138
- * saving state.
13139
- * @type array
13140
- * @default []
13141
- */
13142
- "aoStateSaveParams": [],
13143
-
13144
- /**
13145
- * Callbacks for modifying the settings that have been stored for state saving
13146
- * prior to using the stored values to restore the state.
13147
- * @type array
13148
- * @default []
13149
- */
13150
- "aoStateLoadParams": [],
13151
-
13152
- /**
13153
- * Callbacks for operating on the settings object once the saved state has been
13154
- * loaded
13155
- * @type array
13156
- * @default []
13157
- */
13158
- "aoStateLoaded": [],
13159
-
13160
- /**
13161
- * Cache the table ID for quick access
13162
- * @type string
13163
- * @default <i>Empty string</i>
13164
- */
13165
- "sTableId": "",
13166
-
13167
- /**
13168
- * The TABLE node for the main table
13169
- * @type node
13170
- * @default null
13171
- */
13172
- "nTable": null,
13173
-
13174
- /**
13175
- * Permanent ref to the thead element
13176
- * @type node
13177
- * @default null
13178
- */
13179
- "nTHead": null,
13180
-
13181
- /**
13182
- * Permanent ref to the tfoot element - if it exists
13183
- * @type node
13184
- * @default null
13185
- */
13186
- "nTFoot": null,
13187
-
13188
- /**
13189
- * Permanent ref to the tbody element
13190
- * @type node
13191
- * @default null
13192
- */
13193
- "nTBody": null,
13194
-
13195
- /**
13196
- * Cache the wrapper node (contains all DataTables controlled elements)
13197
- * @type node
13198
- * @default null
13199
- */
13200
- "nTableWrapper": null,
13201
-
13202
- /**
13203
- * Indicate if when using server-side processing the loading of data
13204
- * should be deferred until the second draw.
13205
- * Note that this parameter will be set by the initialisation routine. To
13206
- * set a default use {@link DataTable.defaults}.
13207
- * @type boolean
13208
- * @default false
13209
- */
13210
- "bDeferLoading": false,
13211
-
13212
- /**
13213
- * Indicate if all required information has been read in
13214
- * @type boolean
13215
- * @default false
13216
- */
13217
- "bInitialised": false,
13218
-
13219
- /**
13220
- * Information about open rows. Each object in the array has the parameters
13221
- * 'nTr' and 'nParent'
13222
- * @type array
13223
- * @default []
13224
- */
13225
- "aoOpenRows": [],
13226
-
13227
- /**
13228
- * Dictate the positioning of DataTables' control elements - see
13229
- * {@link DataTable.model.oInit.sDom}.
13230
- * Note that this parameter will be set by the initialisation routine. To
13231
- * set a default use {@link DataTable.defaults}.
13232
- * @type string
13233
- * @default null
13234
- */
13235
- "sDom": null,
13236
-
13237
- /**
13238
- * Search delay (in mS)
13239
- * @type integer
13240
- * @default null
13241
- */
13242
- "searchDelay": null,
13243
-
13244
- /**
13245
- * Which type of pagination should be used.
13246
- * Note that this parameter will be set by the initialisation routine. To
13247
- * set a default use {@link DataTable.defaults}.
13248
- * @type string
13249
- * @default two_button
13250
- */
13251
- "sPaginationType": "two_button",
13252
-
13253
- /**
13254
- * The state duration (for `stateSave`) in seconds.
13255
- * Note that this parameter will be set by the initialisation routine. To
13256
- * set a default use {@link DataTable.defaults}.
13257
- * @type int
13258
- * @default 0
13259
- */
13260
- "iStateDuration": 0,
13261
-
13262
- /**
13263
- * Array of callback functions for state saving. Each array element is an
13264
- * object with the following parameters:
13265
- * <ul>
13266
- * <li>function:fn - function to call. Takes two parameters, oSettings
13267
- * and the JSON string to save that has been thus far created. Returns
13268
- * a JSON string to be inserted into a json object
13269
- * (i.e. '"param": [ 0, 1, 2]')</li>
13270
- * <li>string:sName - name of callback</li>
13271
- * </ul>
13272
- * @type array
13273
- * @default []
13274
- */
13275
- "aoStateSave": [],
13276
-
13277
- /**
13278
- * Array of callback functions for state loading. Each array element is an
13279
- * object with the following parameters:
13280
- * <ul>
13281
- * <li>function:fn - function to call. Takes two parameters, oSettings
13282
- * and the object stored. May return false to cancel state loading</li>
13283
- * <li>string:sName - name of callback</li>
13284
- * </ul>
13285
- * @type array
13286
- * @default []
13287
- */
13288
- "aoStateLoad": [],
13289
-
13290
- /**
13291
- * State that was saved. Useful for back reference
13292
- * @type object
13293
- * @default null
13294
- */
13295
- "oSavedState": null,
13296
-
13297
- /**
13298
- * State that was loaded. Useful for back reference
13299
- * @type object
13300
- * @default null
13301
- */
13302
- "oLoadedState": null,
13303
-
13304
- /**
13305
- * Source url for AJAX data for the table.
13306
- * Note that this parameter will be set by the initialisation routine. To
13307
- * set a default use {@link DataTable.defaults}.
13308
- * @type string
13309
- * @default null
13310
- */
13311
- "sAjaxSource": null,
13312
-
13313
- /**
13314
- * Property from a given object from which to read the table data from. This
13315
- * can be an empty string (when not server-side processing), in which case
13316
- * it is assumed an an array is given directly.
13317
- * Note that this parameter will be set by the initialisation routine. To
13318
- * set a default use {@link DataTable.defaults}.
13319
- * @type string
13320
- */
13321
- "sAjaxDataProp": null,
13322
-
13323
- /**
13324
- * Note if draw should be blocked while getting data
13325
- * @type boolean
13326
- * @default true
13327
- */
13328
- "bAjaxDataGet": true,
13329
-
13330
- /**
13331
- * The last jQuery XHR object that was used for server-side data gathering.
13332
- * This can be used for working with the XHR information in one of the
13333
- * callbacks
13334
- * @type object
13335
- * @default null
13336
- */
13337
- "jqXHR": null,
13338
-
13339
- /**
13340
- * JSON returned from the server in the last Ajax request
13341
- * @type object
13342
- * @default undefined
13343
- */
13344
- "json": undefined,
13345
-
13346
- /**
13347
- * Data submitted as part of the last Ajax request
13348
- * @type object
13349
- * @default undefined
13350
- */
13351
- "oAjaxData": undefined,
13352
-
13353
- /**
13354
- * Function to get the server-side data.
13355
- * Note that this parameter will be set by the initialisation routine. To
13356
- * set a default use {@link DataTable.defaults}.
13357
- * @type function
13358
- */
13359
- "fnServerData": null,
13360
-
13361
- /**
13362
- * Functions which are called prior to sending an Ajax request so extra
13363
- * parameters can easily be sent to the server
13364
- * @type array
13365
- * @default []
13366
- */
13367
- "aoServerParams": [],
13368
-
13369
- /**
13370
- * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13371
- * required).
13372
- * Note that this parameter will be set by the initialisation routine. To
13373
- * set a default use {@link DataTable.defaults}.
13374
- * @type string
13375
- */
13376
- "sServerMethod": null,
13377
-
13378
- /**
13379
- * Format numbers for display.
13380
- * Note that this parameter will be set by the initialisation routine. To
13381
- * set a default use {@link DataTable.defaults}.
13382
- * @type function
13383
- */
13384
- "fnFormatNumber": null,
13385
-
13386
- /**
13387
- * List of options that can be used for the user selectable length menu.
13388
- * Note that this parameter will be set by the initialisation routine. To
13389
- * set a default use {@link DataTable.defaults}.
13390
- * @type array
13391
- * @default []
13392
- */
13393
- "aLengthMenu": null,
13394
-
13395
- /**
13396
- * Counter for the draws that the table does. Also used as a tracker for
13397
- * server-side processing
13398
- * @type int
13399
- * @default 0
13400
- */
13401
- "iDraw": 0,
13402
-
13403
- /**
13404
- * Indicate if a redraw is being done - useful for Ajax
13405
- * @type boolean
13406
- * @default false
13407
- */
13408
- "bDrawing": false,
13409
-
13410
- /**
13411
- * Draw index (iDraw) of the last error when parsing the returned data
13412
- * @type int
13413
- * @default -1
13414
- */
13415
- "iDrawError": -1,
13416
-
13417
- /**
13418
- * Paging display length
13419
- * @type int
13420
- * @default 10
13421
- */
13422
- "_iDisplayLength": 10,
13423
-
13424
- /**
13425
- * Paging start point - aiDisplay index
13426
- * @type int
13427
- * @default 0
13428
- */
13429
- "_iDisplayStart": 0,
13430
-
13431
- /**
13432
- * Server-side processing - number of records in the result set
13433
- * (i.e. before filtering), Use fnRecordsTotal rather than
13434
- * this property to get the value of the number of records, regardless of
13435
- * the server-side processing setting.
13436
- * @type int
13437
- * @default 0
13438
- * @private
13439
- */
13440
- "_iRecordsTotal": 0,
13441
-
13442
- /**
13443
- * Server-side processing - number of records in the current display set
13444
- * (i.e. after filtering). Use fnRecordsDisplay rather than
13445
- * this property to get the value of the number of records, regardless of
13446
- * the server-side processing setting.
13447
- * @type boolean
13448
- * @default 0
13449
- * @private
13450
- */
13451
- "_iRecordsDisplay": 0,
13452
-
13453
- /**
13454
- * Flag to indicate if jQuery UI marking and classes should be used.
13455
- * Note that this parameter will be set by the initialisation routine. To
13456
- * set a default use {@link DataTable.defaults}.
13457
- * @type boolean
13458
- */
13459
- "bJUI": null,
13460
-
13461
- /**
13462
- * The classes to use for the table
13463
- * @type object
13464
- * @default {}
13465
- */
13466
- "oClasses": {},
13467
-
13468
- /**
13469
- * Flag attached to the settings object so you can check in the draw
13470
- * callback if filtering has been done in the draw. Deprecated in favour of
13471
- * events.
13472
- * @type boolean
13473
- * @default false
13474
- * @deprecated
13475
- */
13476
- "bFiltered": false,
13477
-
13478
- /**
13479
- * Flag attached to the settings object so you can check in the draw
13480
- * callback if sorting has been done in the draw. Deprecated in favour of
13481
- * events.
13482
- * @type boolean
13483
- * @default false
13484
- * @deprecated
13485
- */
13486
- "bSorted": false,
13487
-
13488
- /**
13489
- * Indicate that if multiple rows are in the header and there is more than
13490
- * one unique cell per column, if the top one (true) or bottom one (false)
13491
- * should be used for sorting / title by DataTables.
13492
- * Note that this parameter will be set by the initialisation routine. To
13493
- * set a default use {@link DataTable.defaults}.
13494
- * @type boolean
13495
- */
13496
- "bSortCellsTop": null,
13497
-
13498
- /**
13499
- * Initialisation object that is used for the table
13500
- * @type object
13501
- * @default null
13502
- */
13503
- "oInit": null,
13504
-
13505
- /**
13506
- * Destroy callback functions - for plug-ins to attach themselves to the
13507
- * destroy so they can clean up markup and events.
13508
- * @type array
13509
- * @default []
13510
- */
13511
- "aoDestroyCallback": [],
13512
-
13513
-
13514
- /**
13515
- * Get the number of records in the current record set, before filtering
13516
- * @type function
13517
- */
13518
- "fnRecordsTotal": function ()
13519
- {
13520
- return _fnDataSource( this ) == 'ssp' ?
13521
- this._iRecordsTotal * 1 :
13522
- this.aiDisplayMaster.length;
13523
- },
13524
-
13525
- /**
13526
- * Get the number of records in the current record set, after filtering
13527
- * @type function
13528
- */
13529
- "fnRecordsDisplay": function ()
13530
- {
13531
- return _fnDataSource( this ) == 'ssp' ?
13532
- this._iRecordsDisplay * 1 :
13533
- this.aiDisplay.length;
13534
- },
13535
-
13536
- /**
13537
- * Get the display end point - aiDisplay index
13538
- * @type function
13539
- */
13540
- "fnDisplayEnd": function ()
13541
- {
13542
- var
13543
- len = this._iDisplayLength,
13544
- start = this._iDisplayStart,
13545
- calc = start + len,
13546
- records = this.aiDisplay.length,
13547
- features = this.oFeatures,
13548
- paginate = features.bPaginate;
13549
-
13550
- if ( features.bServerSide ) {
13551
- return paginate === false || len === -1 ?
13552
- start + records :
13553
- Math.min( start+len, this._iRecordsDisplay );
13554
- }
13555
- else {
13556
- return ! paginate || calc>records || len===-1 ?
13557
- records :
13558
- calc;
13559
- }
13560
- },
13561
-
13562
- /**
13563
- * The DataTables object for this table
13564
- * @type object
13565
- * @default null
13566
- */
13567
- "oInstance": null,
13568
-
13569
- /**
13570
- * Unique identifier for each instance of the DataTables object. If there
13571
- * is an ID on the table node, then it takes that value, otherwise an
13572
- * incrementing internal counter is used.
13573
- * @type string
13574
- * @default null
13575
- */
13576
- "sInstance": null,
13577
-
13578
- /**
13579
- * tabindex attribute value that is added to DataTables control elements, allowing
13580
- * keyboard navigation of the table and its controls.
13581
- */
13582
- "iTabIndex": 0,
13583
-
13584
- /**
13585
- * DIV container for the footer scrolling table if scrolling
13586
- */
13587
- "nScrollHead": null,
13588
-
13589
- /**
13590
- * DIV container for the footer scrolling table if scrolling
13591
- */
13592
- "nScrollFoot": null,
13593
-
13594
- /**
13595
- * Last applied sort
13596
- * @type array
13597
- * @default []
13598
- */
13599
- "aLastSort": [],
13600
-
13601
- /**
13602
- * Stored plug-in instances
13603
- * @type object
13604
- * @default {}
13605
- */
13606
- "oPlugins": {},
13607
-
13608
- /**
13609
- * Function used to get a row's id from the row's data
13610
- * @type function
13611
- * @default null
13612
- */
13613
- "rowIdFn": null,
13614
-
13615
- /**
13616
- * Data location where to store a row's id
13617
- * @type string
13618
- * @default null
13619
- */
13620
- "rowId": null
13621
- };
13622
-
13623
- /**
13624
- * Extension object for DataTables that is used to provide all extension
13625
- * options.
13626
- *
13627
- * Note that the `DataTable.ext` object is available through
13628
- * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13629
- * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13630
- * @namespace
13631
- * @extends DataTable.models.ext
13632
- */
13633
-
13634
-
13635
- /**
13636
- * DataTables extensions
13637
- *
13638
- * This namespace acts as a collection area for plug-ins that can be used to
13639
- * extend DataTables capabilities. Indeed many of the build in methods
13640
- * use this method to provide their own capabilities (sorting methods for
13641
- * example).
13642
- *
13643
- * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13644
- * reasons
13645
- *
13646
- * @namespace
13647
- */
13648
- DataTable.ext = _ext = {
13649
- /**
13650
- * Buttons. For use with the Buttons extension for DataTables. This is
13651
- * defined here so other extensions can define buttons regardless of load
13652
- * order. It is _not_ used by DataTables core.
13653
- *
13654
- * @type object
13655
- * @default {}
13656
- */
13657
- buttons: {},
13658
-
13659
-
13660
- /**
13661
- * Element class names
13662
- *
13663
- * @type object
13664
- * @default {}
13665
- */
13666
- classes: {},
13667
-
13668
-
13669
- /**
13670
- * Error reporting.
13671
- *
13672
- * How should DataTables report an error. Can take the value 'alert',
13673
- * 'throw', 'none' or a function.
13674
- *
13675
- * @type string|function
13676
- * @default alert
13677
- */
13678
- errMode: "alert",
13679
-
13680
-
13681
- /**
13682
- * Feature plug-ins.
13683
- *
13684
- * This is an array of objects which describe the feature plug-ins that are
13685
- * available to DataTables. These feature plug-ins are then available for
13686
- * use through the `dom` initialisation option.
13687
- *
13688
- * Each feature plug-in is described by an object which must have the
13689
- * following properties:
13690
- *
13691
- * * `fnInit` - function that is used to initialise the plug-in,
13692
- * * `cFeature` - a character so the feature can be enabled by the `dom`
13693
- * instillation option. This is case sensitive.
13694
- *
13695
- * The `fnInit` function has the following input parameters:
13696
- *
13697
- * 1. `{object}` DataTables settings object: see
13698
- * {@link DataTable.models.oSettings}
13699
- *
13700
- * And the following return is expected:
13701
- *
13702
- * * {node|null} The element which contains your feature. Note that the
13703
- * return may also be void if your plug-in does not require to inject any
13704
- * DOM elements into DataTables control (`dom`) - for example this might
13705
- * be useful when developing a plug-in which allows table control via
13706
- * keyboard entry
13707
- *
13708
- * @type array
13709
- *
13710
- * @example
13711
- * $.fn.dataTable.ext.features.push( {
13712
- * "fnInit": function( oSettings ) {
13713
- * return new TableTools( { "oDTSettings": oSettings } );
13714
- * },
13715
- * "cFeature": "T"
13716
- * } );
13717
- */
13718
- feature: [],
13719
-
13720
-
13721
- /**
13722
- * Row searching.
13723
- *
13724
- * This method of searching is complimentary to the default type based
13725
- * searching, and a lot more comprehensive as it allows you complete control
13726
- * over the searching logic. Each element in this array is a function
13727
- * (parameters described below) that is called for every row in the table,
13728
- * and your logic decides if it should be included in the searching data set
13729
- * or not.
13730
- *
13731
- * Searching functions have the following input parameters:
13732
- *
13733
- * 1. `{object}` DataTables settings object: see
13734
- * {@link DataTable.models.oSettings}
13735
- * 2. `{array|object}` Data for the row to be processed (same as the
13736
- * original format that was passed in as the data source, or an array
13737
- * from a DOM data source
13738
- * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13739
- * can be useful to retrieve the `TR` element if you need DOM interaction.
13740
- *
13741
- * And the following return is expected:
13742
- *
13743
- * * {boolean} Include the row in the searched result set (true) or not
13744
- * (false)
13745
- *
13746
- * Note that as with the main search ability in DataTables, technically this
13747
- * is "filtering", since it is subtractive. However, for consistency in
13748
- * naming we call it searching here.
13749
- *
13750
- * @type array
13751
- * @default []
13752
- *
13753
- * @example
13754
- * // The following example shows custom search being applied to the
13755
- * // fourth column (i.e. the data[3] index) based on two input values
13756
- * // from the end-user, matching the data in a certain range.
13757
- * $.fn.dataTable.ext.search.push(
13758
- * function( settings, data, dataIndex ) {
13759
- * var min = document.getElementById('min').value * 1;
13760
- * var max = document.getElementById('max').value * 1;
13761
- * var version = data[3] == "-" ? 0 : data[3]*1;
13762
- *
13763
- * if ( min == "" && max == "" ) {
13764
- * return true;
13765
- * }
13766
- * else if ( min == "" && version < max ) {
13767
- * return true;
13768
- * }
13769
- * else if ( min < version && "" == max ) {
13770
- * return true;
13771
- * }
13772
- * else if ( min < version && version < max ) {
13773
- * return true;
13774
- * }
13775
- * return false;
13776
- * }
13777
- * );
13778
- */
13779
- search: [],
13780
-
13781
-
13782
- /**
13783
- * Selector extensions
13784
- *
13785
- * The `selector` option can be used to extend the options available for the
13786
- * selector modifier options (`selector-modifier` object data type) that
13787
- * each of the three built in selector types offer (row, column and cell +
13788
- * their plural counterparts). For example the Select extension uses this
13789
- * mechanism to provide an option to select only rows, columns and cells
13790
- * that have been marked as selected by the end user (`{selected: true}`),
13791
- * which can be used in conjunction with the existing built in selector
13792
- * options.
13793
- *
13794
- * Each property is an array to which functions can be pushed. The functions
13795
- * take three attributes:
13796
- *
13797
- * * Settings object for the host table
13798
- * * Options object (`selector-modifier` object type)
13799
- * * Array of selected item indexes
13800
- *
13801
- * The return is an array of the resulting item indexes after the custom
13802
- * selector has been applied.
13803
- *
13804
- * @type object
13805
- */
13806
- selector: {
13807
- cell: [],
13808
- column: [],
13809
- row: []
13810
- },
13811
-
13812
-
13813
- /**
13814
- * Internal functions, exposed for used in plug-ins.
13815
- *
13816
- * Please note that you should not need to use the internal methods for
13817
- * anything other than a plug-in (and even then, try to avoid if possible).
13818
- * The internal function may change between releases.
13819
- *
13820
- * @type object
13821
- * @default {}
13822
- */
13823
- internal: {},
13824
-
13825
-
13826
- /**
13827
- * Legacy configuration options. Enable and disable legacy options that
13828
- * are available in DataTables.
13829
- *
13830
- * @type object
13831
- */
13832
- legacy: {
13833
- /**
13834
- * Enable / disable DataTables 1.9 compatible server-side processing
13835
- * requests
13836
- *
13837
- * @type boolean
13838
- * @default null
13839
- */
13840
- ajax: null
13841
- },
13842
-
13843
-
13844
- /**
13845
- * Pagination plug-in methods.
13846
- *
13847
- * Each entry in this object is a function and defines which buttons should
13848
- * be shown by the pagination rendering method that is used for the table:
13849
- * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
13850
- * buttons are displayed in the document, while the functions here tell it
13851
- * what buttons to display. This is done by returning an array of button
13852
- * descriptions (what each button will do).
13853
- *
13854
- * Pagination types (the four built in options and any additional plug-in
13855
- * options defined here) can be used through the `paginationType`
13856
- * initialisation parameter.
13857
- *
13858
- * The functions defined take two parameters:
13859
- *
13860
- * 1. `{int} page` The current page index
13861
- * 2. `{int} pages` The number of pages in the table
13862
- *
13863
- * Each function is expected to return an array where each element of the
13864
- * array can be one of:
13865
- *
13866
- * * `first` - Jump to first page when activated
13867
- * * `last` - Jump to last page when activated
13868
- * * `previous` - Show previous page when activated
13869
- * * `next` - Show next page when activated
13870
- * * `{int}` - Show page of the index given
13871
- * * `{array}` - A nested array containing the above elements to add a
13872
- * containing 'DIV' element (might be useful for styling).
13873
- *
13874
- * Note that DataTables v1.9- used this object slightly differently whereby
13875
- * an object with two functions would be defined for each plug-in. That
13876
- * ability is still supported by DataTables 1.10+ to provide backwards
13877
- * compatibility, but this option of use is now decremented and no longer
13878
- * documented in DataTables 1.10+.
13879
- *
13880
- * @type object
13881
- * @default {}
13882
- *
13883
- * @example
13884
- * // Show previous, next and current page buttons only
13885
- * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
13886
- * return [ 'previous', page, 'next' ];
13887
- * };
13888
- */
13889
- pager: {},
13890
-
13891
-
13892
- renderer: {
13893
- pageButton: {},
13894
- header: {}
13895
- },
13896
-
13897
-
13898
- /**
13899
- * Ordering plug-ins - custom data source
13900
- *
13901
- * The extension options for ordering of data available here is complimentary
13902
- * to the default type based ordering that DataTables typically uses. It
13903
- * allows much greater control over the the data that is being used to
13904
- * order a column, but is necessarily therefore more complex.
13905
- *
13906
- * This type of ordering is useful if you want to do ordering based on data
13907
- * live from the DOM (for example the contents of an 'input' element) rather
13908
- * than just the static string that DataTables knows of.
13909
- *
13910
- * The way these plug-ins work is that you create an array of the values you
13911
- * wish to be ordering for the column in question and then return that
13912
- * array. The data in the array much be in the index order of the rows in
13913
- * the table (not the currently ordering order!). Which order data gathering
13914
- * function is run here depends on the `dt-init columns.orderDataType`
13915
- * parameter that is used for the column (if any).
13916
- *
13917
- * The functions defined take two parameters:
13918
- *
13919
- * 1. `{object}` DataTables settings object: see
13920
- * {@link DataTable.models.oSettings}
13921
- * 2. `{int}` Target column index
13922
- *
13923
- * Each function is expected to return an array:
13924
- *
13925
- * * `{array}` Data for the column to be ordering upon
13926
- *
13927
- * @type array
13928
- *
13929
- * @example
13930
- * // Ordering using `input` node values
13931
- * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
13932
- * {
13933
- * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
13934
- * return $('input', td).val();
13935
- * } );
13936
- * }
13937
- */
13938
- order: {},
13939
-
13940
-
13941
- /**
13942
- * Type based plug-ins.
13943
- *
13944
- * Each column in DataTables has a type assigned to it, either by automatic
13945
- * detection or by direct assignment using the `type` option for the column.
13946
- * The type of a column will effect how it is ordering and search (plug-ins
13947
- * can also make use of the column type if required).
13948
- *
13949
- * @namespace
13950
- */
13951
- type: {
13952
- /**
13953
- * Type detection functions.
13954
- *
13955
- * The functions defined in this object are used to automatically detect
13956
- * a column's type, making initialisation of DataTables super easy, even
13957
- * when complex data is in the table.
13958
- *
13959
- * The functions defined take two parameters:
13960
- *
13961
- * 1. `{*}` Data from the column cell to be analysed
13962
- * 2. `{settings}` DataTables settings object. This can be used to
13963
- * perform context specific type detection - for example detection
13964
- * based on language settings such as using a comma for a decimal
13965
- * place. Generally speaking the options from the settings will not
13966
- * be required
13967
- *
13968
- * Each function is expected to return:
13969
- *
13970
- * * `{string|null}` Data type detected, or null if unknown (and thus
13971
- * pass it on to the other type detection functions.
13972
- *
13973
- * @type array
13974
- *
13975
- * @example
13976
- * // Currency type detection plug-in:
13977
- * $.fn.dataTable.ext.type.detect.push(
13978
- * function ( data, settings ) {
13979
- * // Check the numeric part
13980
- * if ( ! $.isNumeric( data.substring(1) ) ) {
13981
- * return null;
13982
- * }
13983
- *
13984
- * // Check prefixed by currency
13985
- * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
13986
- * return 'currency';
13987
- * }
13988
- * return null;
13989
- * }
13990
- * );
13991
- */
13992
- detect: [],
13993
-
13994
-
13995
- /**
13996
- * Type based search formatting.
13997
- *
13998
- * The type based searching functions can be used to pre-format the
13999
- * data to be search on. For example, it can be used to strip HTML
14000
- * tags or to de-format telephone numbers for numeric only searching.
14001
- *
14002
- * Note that is a search is not defined for a column of a given type,
14003
- * no search formatting will be performed.
14004
- *
14005
- * Pre-processing of searching data plug-ins - When you assign the sType
14006
- * for a column (or have it automatically detected for you by DataTables
14007
- * or a type detection plug-in), you will typically be using this for
14008
- * custom sorting, but it can also be used to provide custom searching
14009
- * by allowing you to pre-processing the data and returning the data in
14010
- * the format that should be searched upon. This is done by adding
14011
- * functions this object with a parameter name which matches the sType
14012
- * for that target column. This is the corollary of <i>afnSortData</i>
14013
- * for searching data.
14014
- *
14015
- * The functions defined take a single parameter:
14016
- *
14017
- * 1. `{*}` Data from the column cell to be prepared for searching
14018
- *
14019
- * Each function is expected to return:
14020
- *
14021
- * * `{string|null}` Formatted string that will be used for the searching.
14022
- *
14023
- * @type object
14024
- * @default {}
14025
- *
14026
- * @example
14027
- * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14028
- * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14029
- * }
14030
- */
14031
- search: {},
14032
-
14033
-
14034
- /**
14035
- * Type based ordering.
14036
- *
14037
- * The column type tells DataTables what ordering to apply to the table
14038
- * when a column is sorted upon. The order for each type that is defined,
14039
- * is defined by the functions available in this object.
14040
- *
14041
- * Each ordering option can be described by three properties added to
14042
- * this object:
14043
- *
14044
- * * `{type}-pre` - Pre-formatting function
14045
- * * `{type}-asc` - Ascending order function
14046
- * * `{type}-desc` - Descending order function
14047
- *
14048
- * All three can be used together, only `{type}-pre` or only
14049
- * `{type}-asc` and `{type}-desc` together. It is generally recommended
14050
- * that only `{type}-pre` is used, as this provides the optimal
14051
- * implementation in terms of speed, although the others are provided
14052
- * for compatibility with existing Javascript sort functions.
14053
- *
14054
- * `{type}-pre`: Functions defined take a single parameter:
14055
- *
14056
- * 1. `{*}` Data from the column cell to be prepared for ordering
14057
- *
14058
- * And return:
14059
- *
14060
- * * `{*}` Data to be sorted upon
14061
- *
14062
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14063
- * functions, taking two parameters:
14064
- *
14065
- * 1. `{*}` Data to compare to the second parameter
14066
- * 2. `{*}` Data to compare to the first parameter
14067
- *
14068
- * And returning:
14069
- *
14070
- * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14071
- * than the second parameter, ===0 if the two parameters are equal and
14072
- * >0 if the first parameter should be sorted height than the second
14073
- * parameter.
14074
- *
14075
- * @type object
14076
- * @default {}
14077
- *
14078
- * @example
14079
- * // Numeric ordering of formatted numbers with a pre-formatter
14080
- * $.extend( $.fn.dataTable.ext.type.order, {
14081
- * "string-pre": function(x) {
14082
- * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14083
- * return parseFloat( a );
14084
- * }
14085
- * } );
14086
- *
14087
- * @example
14088
- * // Case-sensitive string ordering, with no pre-formatting method
14089
- * $.extend( $.fn.dataTable.ext.order, {
14090
- * "string-case-asc": function(x,y) {
14091
- * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14092
- * },
14093
- * "string-case-desc": function(x,y) {
14094
- * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14095
- * }
14096
- * } );
14097
- */
14098
- order: {}
14099
- },
14100
-
14101
- /**
14102
- * Unique DataTables instance counter
14103
- *
14104
- * @type int
14105
- * @private
14106
- */
14107
- _unique: 0,
14108
-
14109
-
14110
- //
14111
- // Depreciated
14112
- // The following properties are retained for backwards compatiblity only.
14113
- // The should not be used in new projects and will be removed in a future
14114
- // version
14115
- //
14116
-
14117
- /**
14118
- * Version check function.
14119
- * @type function
14120
- * @depreciated Since 1.10
14121
- */
14122
- fnVersionCheck: DataTable.fnVersionCheck,
14123
-
14124
-
14125
- /**
14126
- * Index for what 'this' index API functions should use
14127
- * @type int
14128
- * @deprecated Since v1.10
14129
- */
14130
- iApiIndex: 0,
14131
-
14132
-
14133
- /**
14134
- * jQuery UI class container
14135
- * @type object
14136
- * @deprecated Since v1.10
14137
- */
14138
- oJUIClasses: {},
14139
-
14140
-
14141
- /**
14142
- * Software version
14143
- * @type string
14144
- * @deprecated Since v1.10
14145
- */
14146
- sVersion: DataTable.version
14147
- };
14148
-
14149
-
14150
- //
14151
- // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14152
- //
14153
- $.extend( _ext, {
14154
- afnFiltering: _ext.search,
14155
- aTypes: _ext.type.detect,
14156
- ofnSearch: _ext.type.search,
14157
- oSort: _ext.type.order,
14158
- afnSortData: _ext.order,
14159
- aoFeatures: _ext.feature,
14160
- oApi: _ext.internal,
14161
- oStdClasses: _ext.classes,
14162
- oPagination: _ext.pager
14163
- } );
14164
-
14165
-
14166
- $.extend( DataTable.ext.classes, {
14167
- "sTable": "dataTable",
14168
- "sNoFooter": "no-footer",
14169
-
14170
- /* Paging buttons */
14171
- "sPageButton": "paginate_button",
14172
- "sPageButtonActive": "current",
14173
- "sPageButtonDisabled": "disabled",
14174
-
14175
- /* Striping classes */
14176
- "sStripeOdd": "odd",
14177
- "sStripeEven": "even",
14178
-
14179
- /* Empty row */
14180
- "sRowEmpty": "dataTables_empty",
14181
-
14182
- /* Features */
14183
- "sWrapper": "dataTables_wrapper",
14184
- "sFilter": "dataTables_filter",
14185
- "sInfo": "dataTables_info",
14186
- "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14187
- "sLength": "dataTables_length",
14188
- "sProcessing": "dataTables_processing",
14189
-
14190
- /* Sorting */
14191
- "sSortAsc": "sorting_asc",
14192
- "sSortDesc": "sorting_desc",
14193
- "sSortable": "sorting", /* Sortable in both directions */
14194
- "sSortableAsc": "sorting_asc_disabled",
14195
- "sSortableDesc": "sorting_desc_disabled",
14196
- "sSortableNone": "sorting_disabled",
14197
- "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14198
-
14199
- /* Filtering */
14200
- "sFilterInput": "",
14201
-
14202
- /* Page length */
14203
- "sLengthSelect": "",
14204
-
14205
- /* Scrolling */
14206
- "sScrollWrapper": "dataTables_scroll",
14207
- "sScrollHead": "dataTables_scrollHead",
14208
- "sScrollHeadInner": "dataTables_scrollHeadInner",
14209
- "sScrollBody": "dataTables_scrollBody",
14210
- "sScrollFoot": "dataTables_scrollFoot",
14211
- "sScrollFootInner": "dataTables_scrollFootInner",
14212
-
14213
- /* Misc */
14214
- "sHeaderTH": "",
14215
- "sFooterTH": "",
14216
-
14217
- // Deprecated
14218
- "sSortJUIAsc": "",
14219
- "sSortJUIDesc": "",
14220
- "sSortJUI": "",
14221
- "sSortJUIAscAllowed": "",
14222
- "sSortJUIDescAllowed": "",
14223
- "sSortJUIWrapper": "",
14224
- "sSortIcon": "",
14225
- "sJUIHeader": "",
14226
- "sJUIFooter": ""
14227
- } );
14228
-
14229
-
14230
- (function() {
14231
-
14232
- // Reused strings for better compression. Closure compiler appears to have a
14233
- // weird edge case where it is trying to expand strings rather than use the
14234
- // variable version. This results in about 200 bytes being added, for very
14235
- // little preference benefit since it this run on script load only.
14236
- var _empty = '';
14237
- _empty = '';
14238
-
14239
- var _stateDefault = _empty + 'ui-state-default';
14240
- var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
14241
- var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
14242
-
14243
- $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
14244
- /* Full numbers paging buttons */
14245
- "sPageButton": "fg-button ui-button "+_stateDefault,
14246
- "sPageButtonActive": "ui-state-disabled",
14247
- "sPageButtonDisabled": "ui-state-disabled",
14248
-
14249
- /* Features */
14250
- "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
14251
- "ui-buttonset-multi paging_", /* Note that the type is postfixed */
14252
-
14253
- /* Sorting */
14254
- "sSortAsc": _stateDefault+" sorting_asc",
14255
- "sSortDesc": _stateDefault+" sorting_desc",
14256
- "sSortable": _stateDefault+" sorting",
14257
- "sSortableAsc": _stateDefault+" sorting_asc_disabled",
14258
- "sSortableDesc": _stateDefault+" sorting_desc_disabled",
14259
- "sSortableNone": _stateDefault+" sorting_disabled",
14260
- "sSortJUIAsc": _sortIcon+"triangle-1-n",
14261
- "sSortJUIDesc": _sortIcon+"triangle-1-s",
14262
- "sSortJUI": _sortIcon+"carat-2-n-s",
14263
- "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
14264
- "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
14265
- "sSortJUIWrapper": "DataTables_sort_wrapper",
14266
- "sSortIcon": "DataTables_sort_icon",
14267
-
14268
- /* Scrolling */
14269
- "sScrollHead": "dataTables_scrollHead "+_stateDefault,
14270
- "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
14271
-
14272
- /* Misc */
14273
- "sHeaderTH": _stateDefault,
14274
- "sFooterTH": _stateDefault,
14275
- "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
14276
- "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
14277
- } );
14278
-
14279
- }());
14280
-
14281
-
14282
-
14283
- var extPagination = DataTable.ext.pager;
14284
-
14285
- function _numbers ( page, pages ) {
14286
- var
14287
- numbers = [],
14288
- buttons = extPagination.numbers_length,
14289
- half = Math.floor( buttons / 2 ),
14290
- i = 1;
14291
-
14292
- if ( pages <= buttons ) {
14293
- numbers = _range( 0, pages );
14294
- }
14295
- else if ( page <= half ) {
14296
- numbers = _range( 0, buttons-2 );
14297
- numbers.push( 'ellipsis' );
14298
- numbers.push( pages-1 );
14299
- }
14300
- else if ( page >= pages - 1 - half ) {
14301
- numbers = _range( pages-(buttons-2), pages );
14302
- numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14303
- numbers.splice( 0, 0, 0 );
14304
- }
14305
- else {
14306
- numbers = _range( page-half+2, page+half-1 );
14307
- numbers.push( 'ellipsis' );
14308
- numbers.push( pages-1 );
14309
- numbers.splice( 0, 0, 'ellipsis' );
14310
- numbers.splice( 0, 0, 0 );
14311
- }
14312
-
14313
- numbers.DT_el = 'span';
14314
- return numbers;
14315
- }
14316
-
14317
-
14318
- $.extend( extPagination, {
14319
- simple: function ( page, pages ) {
14320
- return [ 'previous', 'next' ];
14321
- },
14322
-
14323
- full: function ( page, pages ) {
14324
- return [ 'first', 'previous', 'next', 'last' ];
14325
- },
14326
-
14327
- numbers: function ( page, pages ) {
14328
- return [ _numbers(page, pages) ];
14329
- },
14330
-
14331
- simple_numbers: function ( page, pages ) {
14332
- return [ 'previous', _numbers(page, pages), 'next' ];
14333
- },
14334
-
14335
- full_numbers: function ( page, pages ) {
14336
- return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14337
- },
14338
-
14339
- // For testing and plug-ins to use
14340
- _numbers: _numbers,
14341
-
14342
- // Number of number buttons (including ellipsis) to show. _Must be odd!_
14343
- numbers_length: 7
14344
- } );
14345
-
14346
-
14347
- $.extend( true, DataTable.ext.renderer, {
14348
- pageButton: {
14349
- _: function ( settings, host, idx, buttons, page, pages ) {
14350
- var classes = settings.oClasses;
14351
- var lang = settings.oLanguage.oPaginate;
14352
- var btnDisplay, btnClass, counter=0;
14353
-
14354
- var attach = function( container, buttons ) {
14355
- var i, ien, node, button;
14356
- var clickHandler = function ( e ) {
14357
- _fnPageChange( settings, e.data.action, true );
14358
- };
14359
-
14360
- for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14361
- button = buttons[i];
14362
-
14363
- if ( $.isArray( button ) ) {
14364
- var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14365
- .appendTo( container );
14366
- attach( inner, button );
14367
- }
14368
- else {
14369
- btnDisplay = null;
14370
- btnClass = '';
14371
-
14372
- switch ( button ) {
14373
- case 'ellipsis':
14374
- container.append('<span class="ellipsis">&#x2026;</span>');
14375
- break;
14376
-
14377
- case 'first':
14378
- btnDisplay = lang.sFirst;
14379
- btnClass = button + (page > 0 ?
14380
- '' : ' '+classes.sPageButtonDisabled);
14381
- break;
14382
-
14383
- case 'previous':
14384
- btnDisplay = lang.sPrevious;
14385
- btnClass = button + (page > 0 ?
14386
- '' : ' '+classes.sPageButtonDisabled);
14387
- break;
14388
-
14389
- case 'next':
14390
- btnDisplay = lang.sNext;
14391
- btnClass = button + (page < pages-1 ?
14392
- '' : ' '+classes.sPageButtonDisabled);
14393
- break;
14394
-
14395
- case 'last':
14396
- btnDisplay = lang.sLast;
14397
- btnClass = button + (page < pages-1 ?
14398
- '' : ' '+classes.sPageButtonDisabled);
14399
- break;
14400
-
14401
- default:
14402
- btnDisplay = button + 1;
14403
- btnClass = page === button ?
14404
- classes.sPageButtonActive : '';
14405
- break;
14406
- }
14407
-
14408
- if ( btnDisplay !== null ) {
14409
- node = $('<a>', {
14410
- 'class': classes.sPageButton+' '+btnClass,
14411
- 'aria-controls': settings.sTableId,
14412
- 'data-dt-idx': counter,
14413
- 'tabindex': settings.iTabIndex,
14414
- 'id': idx === 0 && typeof button === 'string' ?
14415
- settings.sTableId +'_'+ button :
14416
- null
14417
- } )
14418
- .html( btnDisplay )
14419
- .appendTo( container );
14420
-
14421
- _fnBindAction(
14422
- node, {action: button}, clickHandler
14423
- );
14424
-
14425
- counter++;
14426
- }
14427
- }
14428
- }
14429
- };
14430
-
14431
- // IE9 throws an 'unknown error' if document.activeElement is used
14432
- // inside an iframe or frame. Try / catch the error. Not good for
14433
- // accessibility, but neither are frames.
14434
- var activeEl;
14435
-
14436
- try {
14437
- // Because this approach is destroying and recreating the paging
14438
- // elements, focus is lost on the select button which is bad for
14439
- // accessibility. So we want to restore focus once the draw has
14440
- // completed
14441
- activeEl = $(host).find(document.activeElement).data('dt-idx');
14442
- }
14443
- catch (e) {}
14444
-
14445
- attach( $(host).empty(), buttons );
14446
-
14447
- if ( activeEl ) {
14448
- $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
14449
- }
14450
- }
14451
- }
14452
- } );
14453
-
14454
-
14455
-
14456
- // Built in type detection. See model.ext.aTypes for information about
14457
- // what is required from this methods.
14458
- $.extend( DataTable.ext.type.detect, [
14459
- // Plain numbers - first since V8 detects some plain numbers as dates
14460
- // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14461
- function ( d, settings )
14462
- {
14463
- var decimal = settings.oLanguage.sDecimal;
14464
- return _isNumber( d, decimal ) ? 'num'+decimal : null;
14465
- },
14466
-
14467
- // Dates (only those recognised by the browser's Date.parse)
14468
- function ( d, settings )
14469
- {
14470
- // V8 will remove any unknown characters at the start and end of the
14471
- // expression, leading to false matches such as `$245.12` or `10%` being
14472
- // a valid date. See forum thread 18941 for detail.
14473
- if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
14474
- return null;
14475
- }
14476
- var parsed = Date.parse(d);
14477
- return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14478
- },
14479
-
14480
- // Formatted numbers
14481
- function ( d, settings )
14482
- {
14483
- var decimal = settings.oLanguage.sDecimal;
14484
- return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14485
- },
14486
-
14487
- // HTML numeric
14488
- function ( d, settings )
14489
- {
14490
- var decimal = settings.oLanguage.sDecimal;
14491
- return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14492
- },
14493
-
14494
- // HTML numeric, formatted
14495
- function ( d, settings )
14496
- {
14497
- var decimal = settings.oLanguage.sDecimal;
14498
- return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14499
- },
14500
-
14501
- // HTML (this is strict checking - there must be html)
14502
- function ( d, settings )
14503
- {
14504
- return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14505
- 'html' : null;
14506
- }
14507
- ] );
14508
-
14509
-
14510
-
14511
- // Filter formatting functions. See model.ext.ofnSearch for information about
14512
- // what is required from these methods.
14513
- //
14514
- // Note that additional search methods are added for the html numbers and
14515
- // html formatted numbers by `_addNumericSort()` when we know what the decimal
14516
- // place is
14517
-
14518
-
14519
- $.extend( DataTable.ext.type.search, {
14520
- html: function ( data ) {
14521
- return _empty(data) ?
14522
- data :
14523
- typeof data === 'string' ?
14524
- data
14525
- .replace( _re_new_lines, " " )
14526
- .replace( _re_html, "" ) :
14527
- '';
14528
- },
14529
-
14530
- string: function ( data ) {
14531
- return _empty(data) ?
14532
- data :
14533
- typeof data === 'string' ?
14534
- data.replace( _re_new_lines, " " ) :
14535
- data;
14536
- }
14537
- } );
14538
-
14539
-
14540
-
14541
- var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14542
- if ( d !== 0 && (!d || d === '-') ) {
14543
- return -Infinity;
14544
- }
14545
-
14546
- // If a decimal place other than `.` is used, it needs to be given to the
14547
- // function so we can detect it and replace with a `.` which is the only
14548
- // decimal place Javascript recognises - it is not locale aware.
14549
- if ( decimalPlace ) {
14550
- d = _numToDecimal( d, decimalPlace );
14551
- }
14552
-
14553
- if ( d.replace ) {
14554
- if ( re1 ) {
14555
- d = d.replace( re1, '' );
14556
- }
14557
-
14558
- if ( re2 ) {
14559
- d = d.replace( re2, '' );
14560
- }
14561
- }
14562
-
14563
- return d * 1;
14564
- };
14565
-
14566
-
14567
- // Add the numeric 'deformatting' functions for sorting and search. This is done
14568
- // in a function to provide an easy ability for the language options to add
14569
- // additional methods if a non-period decimal place is used.
14570
- function _addNumericSort ( decimalPlace ) {
14571
- $.each(
14572
- {
14573
- // Plain numbers
14574
- "num": function ( d ) {
14575
- return __numericReplace( d, decimalPlace );
14576
- },
14577
-
14578
- // Formatted numbers
14579
- "num-fmt": function ( d ) {
14580
- return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14581
- },
14582
-
14583
- // HTML numeric
14584
- "html-num": function ( d ) {
14585
- return __numericReplace( d, decimalPlace, _re_html );
14586
- },
14587
-
14588
- // HTML numeric, formatted
14589
- "html-num-fmt": function ( d ) {
14590
- return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14591
- }
14592
- },
14593
- function ( key, fn ) {
14594
- // Add the ordering method
14595
- _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14596
-
14597
- // For HTML types add a search formatter that will strip the HTML
14598
- if ( key.match(/^html\-/) ) {
14599
- _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14600
- }
14601
- }
14602
- );
14603
- }
14604
-
14605
-
14606
- // Default sort methods
14607
- $.extend( _ext.type.order, {
14608
- // Dates
14609
- "date-pre": function ( d ) {
14610
- return Date.parse( d ) || 0;
14611
- },
14612
-
14613
- // html
14614
- "html-pre": function ( a ) {
14615
- return _empty(a) ?
14616
- '' :
14617
- a.replace ?
14618
- a.replace( /<.*?>/g, "" ).toLowerCase() :
14619
- a+'';
14620
- },
14621
-
14622
- // string
14623
- "string-pre": function ( a ) {
14624
- // This is a little complex, but faster than always calling toString,
14625
- // http://jsperf.com/tostring-v-check
14626
- return _empty(a) ?
14627
- '' :
14628
- typeof a === 'string' ?
14629
- a.toLowerCase() :
14630
- ! a.toString ?
14631
- '' :
14632
- a.toString();
14633
- },
14634
-
14635
- // string-asc and -desc are retained only for compatibility with the old
14636
- // sort methods
14637
- "string-asc": function ( x, y ) {
14638
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14639
- },
14640
-
14641
- "string-desc": function ( x, y ) {
14642
- return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14643
- }
14644
- } );
14645
-
14646
-
14647
- // Numeric sorting types - order doesn't matter here
14648
- _addNumericSort( '' );
14649
-
14650
-
14651
- $.extend( true, DataTable.ext.renderer, {
14652
- header: {
14653
- _: function ( settings, cell, column, classes ) {
14654
- // No additional mark-up required
14655
- // Attach a sort listener to update on sort - note that using the
14656
- // `DT` namespace will allow the event to be removed automatically
14657
- // on destroy, while the `dt` namespaced event is the one we are
14658
- // listening for
14659
- $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14660
- if ( settings !== ctx ) { // need to check this this is the host
14661
- return; // table, not a nested one
14662
- }
14663
-
14664
- var colIdx = column.idx;
14665
-
14666
- cell
14667
- .removeClass(
14668
- column.sSortingClass +' '+
14669
- classes.sSortAsc +' '+
14670
- classes.sSortDesc
14671
- )
14672
- .addClass( columns[ colIdx ] == 'asc' ?
14673
- classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14674
- classes.sSortDesc :
14675
- column.sSortingClass
14676
- );
14677
- } );
14678
- },
14679
-
14680
- jqueryui: function ( settings, cell, column, classes ) {
14681
- $('<div/>')
14682
- .addClass( classes.sSortJUIWrapper )
14683
- .append( cell.contents() )
14684
- .append( $('<span/>')
14685
- .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14686
- )
14687
- .appendTo( cell );
14688
-
14689
- // Attach a sort listener to update on sort
14690
- $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14691
- if ( settings !== ctx ) {
14692
- return;
14693
- }
14694
-
14695
- var colIdx = column.idx;
14696
-
14697
- cell
14698
- .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14699
- .addClass( columns[ colIdx ] == 'asc' ?
14700
- classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14701
- classes.sSortDesc :
14702
- column.sSortingClass
14703
- );
14704
-
14705
- cell
14706
- .find( 'span.'+classes.sSortIcon )
14707
- .removeClass(
14708
- classes.sSortJUIAsc +" "+
14709
- classes.sSortJUIDesc +" "+
14710
- classes.sSortJUI +" "+
14711
- classes.sSortJUIAscAllowed +" "+
14712
- classes.sSortJUIDescAllowed
14713
- )
14714
- .addClass( columns[ colIdx ] == 'asc' ?
14715
- classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14716
- classes.sSortJUIDesc :
14717
- column.sSortingClassJUI
14718
- );
14719
- } );
14720
- }
14721
- }
14722
- } );
14723
-
14724
- /*
14725
- * Public helper functions. These aren't used internally by DataTables, or
14726
- * called by any of the options passed into DataTables, but they can be used
14727
- * externally by developers working with DataTables. They are helper functions
14728
- * to make working with DataTables a little bit easier.
14729
- */
14730
-
14731
- /**
14732
- * Helpers for `columns.render`.
14733
- *
14734
- * The options defined here can be used with the `columns.render` initialisation
14735
- * option to provide a display renderer. The following functions are defined:
14736
- *
14737
- * * `number` - Will format numeric data (defined by `columns.data`) for
14738
- * display, retaining the original unformatted data for sorting and filtering.
14739
- * It takes 5 parameters:
14740
- * * `string` - Thousands grouping separator
14741
- * * `string` - Decimal point indicator
14742
- * * `integer` - Number of decimal points to show
14743
- * * `string` (optional) - Prefix.
14744
- * * `string` (optional) - Postfix (/suffix).
14745
- *
14746
- * @example
14747
- * // Column definition using the number renderer
14748
- * {
14749
- * data: "salary",
14750
- * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14751
- * }
14752
- *
14753
- * @namespace
14754
- */
14755
- DataTable.render = {
14756
- number: function ( thousands, decimal, precision, prefix, postfix ) {
14757
- return {
14758
- display: function ( d ) {
14759
- if ( typeof d !== 'number' && typeof d !== 'string' ) {
14760
- return d;
14761
- }
14762
-
14763
- var negative = d < 0 ? '-' : '';
14764
- d = Math.abs( parseFloat( d ) );
14765
-
14766
- var intPart = parseInt( d, 10 );
14767
- var floatPart = precision ?
14768
- decimal+(d - intPart).toFixed( precision ).substring( 2 ):
14769
- '';
14770
-
14771
- return negative + (prefix||'') +
14772
- intPart.toString().replace(
14773
- /\B(?=(\d{3})+(?!\d))/g, thousands
14774
- ) +
14775
- floatPart +
14776
- (postfix||'');
14777
- }
14778
- };
14779
- }
14780
- };
14781
-
14782
-
14783
- /*
14784
- * This is really a good bit rubbish this method of exposing the internal methods
14785
- * publicly... - To be fixed in 2.0 using methods on the prototype
14786
- */
14787
-
14788
-
14789
- /**
14790
- * Create a wrapper function for exporting an internal functions to an external API.
14791
- * @param {string} fn API function name
14792
- * @returns {function} wrapped function
14793
- * @memberof DataTable#internal
14794
- */
14795
- function _fnExternApiFunc (fn)
14796
- {
14797
- return function() {
14798
- var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
14799
- Array.prototype.slice.call(arguments)
14800
- );
14801
- return DataTable.ext.internal[fn].apply( this, args );
14802
- };
14803
- }
14804
-
14805
-
14806
- /**
14807
- * Reference to internal functions for use by plug-in developers. Note that
14808
- * these methods are references to internal functions and are considered to be
14809
- * private. If you use these methods, be aware that they are liable to change
14810
- * between versions.
14811
- * @namespace
14812
- */
14813
- $.extend( DataTable.ext.internal, {
14814
- _fnExternApiFunc: _fnExternApiFunc,
14815
- _fnBuildAjax: _fnBuildAjax,
14816
- _fnAjaxUpdate: _fnAjaxUpdate,
14817
- _fnAjaxParameters: _fnAjaxParameters,
14818
- _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
14819
- _fnAjaxDataSrc: _fnAjaxDataSrc,
14820
- _fnAddColumn: _fnAddColumn,
14821
- _fnColumnOptions: _fnColumnOptions,
14822
- _fnAdjustColumnSizing: _fnAdjustColumnSizing,
14823
- _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
14824
- _fnColumnIndexToVisible: _fnColumnIndexToVisible,
14825
- _fnVisbleColumns: _fnVisbleColumns,
14826
- _fnGetColumns: _fnGetColumns,
14827
- _fnColumnTypes: _fnColumnTypes,
14828
- _fnApplyColumnDefs: _fnApplyColumnDefs,
14829
- _fnHungarianMap: _fnHungarianMap,
14830
- _fnCamelToHungarian: _fnCamelToHungarian,
14831
- _fnLanguageCompat: _fnLanguageCompat,
14832
- _fnBrowserDetect: _fnBrowserDetect,
14833
- _fnAddData: _fnAddData,
14834
- _fnAddTr: _fnAddTr,
14835
- _fnNodeToDataIndex: _fnNodeToDataIndex,
14836
- _fnNodeToColumnIndex: _fnNodeToColumnIndex,
14837
- _fnGetCellData: _fnGetCellData,
14838
- _fnSetCellData: _fnSetCellData,
14839
- _fnSplitObjNotation: _fnSplitObjNotation,
14840
- _fnGetObjectDataFn: _fnGetObjectDataFn,
14841
- _fnSetObjectDataFn: _fnSetObjectDataFn,
14842
- _fnGetDataMaster: _fnGetDataMaster,
14843
- _fnClearTable: _fnClearTable,
14844
- _fnDeleteIndex: _fnDeleteIndex,
14845
- _fnInvalidate: _fnInvalidate,
14846
- _fnGetRowElements: _fnGetRowElements,
14847
- _fnCreateTr: _fnCreateTr,
14848
- _fnBuildHead: _fnBuildHead,
14849
- _fnDrawHead: _fnDrawHead,
14850
- _fnDraw: _fnDraw,
14851
- _fnReDraw: _fnReDraw,
14852
- _fnAddOptionsHtml: _fnAddOptionsHtml,
14853
- _fnDetectHeader: _fnDetectHeader,
14854
- _fnGetUniqueThs: _fnGetUniqueThs,
14855
- _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
14856
- _fnFilterComplete: _fnFilterComplete,
14857
- _fnFilterCustom: _fnFilterCustom,
14858
- _fnFilterColumn: _fnFilterColumn,
14859
- _fnFilter: _fnFilter,
14860
- _fnFilterCreateSearch: _fnFilterCreateSearch,
14861
- _fnEscapeRegex: _fnEscapeRegex,
14862
- _fnFilterData: _fnFilterData,
14863
- _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
14864
- _fnUpdateInfo: _fnUpdateInfo,
14865
- _fnInfoMacros: _fnInfoMacros,
14866
- _fnInitialise: _fnInitialise,
14867
- _fnInitComplete: _fnInitComplete,
14868
- _fnLengthChange: _fnLengthChange,
14869
- _fnFeatureHtmlLength: _fnFeatureHtmlLength,
14870
- _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
14871
- _fnPageChange: _fnPageChange,
14872
- _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
14873
- _fnProcessingDisplay: _fnProcessingDisplay,
14874
- _fnFeatureHtmlTable: _fnFeatureHtmlTable,
14875
- _fnScrollDraw: _fnScrollDraw,
14876
- _fnApplyToChildren: _fnApplyToChildren,
14877
- _fnCalculateColumnWidths: _fnCalculateColumnWidths,
14878
- _fnThrottle: _fnThrottle,
14879
- _fnConvertToWidth: _fnConvertToWidth,
14880
- _fnGetWidestNode: _fnGetWidestNode,
14881
- _fnGetMaxLenString: _fnGetMaxLenString,
14882
- _fnStringToCss: _fnStringToCss,
14883
- _fnScrollBarWidth: _fnScrollBarWidth,
14884
- _fnSortFlatten: _fnSortFlatten,
14885
- _fnSort: _fnSort,
14886
- _fnSortAria: _fnSortAria,
14887
- _fnSortListener: _fnSortListener,
14888
- _fnSortAttachListener: _fnSortAttachListener,
14889
- _fnSortingClasses: _fnSortingClasses,
14890
- _fnSortData: _fnSortData,
14891
- _fnSaveState: _fnSaveState,
14892
- _fnLoadState: _fnLoadState,
14893
- _fnSettingsFromNode: _fnSettingsFromNode,
14894
- _fnLog: _fnLog,
14895
- _fnMap: _fnMap,
14896
- _fnBindAction: _fnBindAction,
14897
- _fnCallbackReg: _fnCallbackReg,
14898
- _fnCallbackFire: _fnCallbackFire,
14899
- _fnLengthOverflow: _fnLengthOverflow,
14900
- _fnRenderer: _fnRenderer,
14901
- _fnDataSource: _fnDataSource,
14902
- _fnRowAttributes: _fnRowAttributes,
14903
- _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
14904
- // in 1.10, so this dead-end function is
14905
- // added to prevent errors
14906
- } );
14907
-
14908
-
14909
- // jQuery access
14910
- $.fn.dataTable = DataTable;
14911
-
14912
- // Legacy aliases
14913
- $.fn.dataTableSettings = DataTable.settings;
14914
- $.fn.dataTableExt = DataTable.ext;
14915
-
14916
- // With a capital `D` we return a DataTables API instance rather than a
14917
- // jQuery object
14918
- $.fn.DataTable = function ( opts ) {
14919
- return $(this).dataTable( opts ).api();
14920
- };
14921
-
14922
- // All properties that are available to $.fn.dataTable should also be
14923
- // available on $.fn.DataTable
14924
- $.each( DataTable, function ( prop, val ) {
14925
- $.fn.DataTable[ prop ] = val;
14926
- } );
14927
-
14928
-
14929
- // Information about events fired by DataTables - for documentation.
14930
- /**
14931
- * Draw event, fired whenever the table is redrawn on the page, at the same
14932
- * point as fnDrawCallback. This may be useful for binding events or
14933
- * performing calculations when the table is altered at all.
14934
- * @name DataTable#draw.dt
14935
- * @event
14936
- * @param {event} e jQuery event object
14937
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14938
- */
14939
-
14940
- /**
14941
- * Search event, fired when the searching applied to the table (using the
14942
- * built-in global search, or column filters) is altered.
14943
- * @name DataTable#search.dt
14944
- * @event
14945
- * @param {event} e jQuery event object
14946
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14947
- */
14948
-
14949
- /**
14950
- * Page change event, fired when the paging of the table is altered.
14951
- * @name DataTable#page.dt
14952
- * @event
14953
- * @param {event} e jQuery event object
14954
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14955
- */
14956
-
14957
- /**
14958
- * Order event, fired when the ordering applied to the table is altered.
14959
- * @name DataTable#order.dt
14960
- * @event
14961
- * @param {event} e jQuery event object
14962
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14963
- */
14964
-
14965
- /**
14966
- * DataTables initialisation complete event, fired when the table is fully
14967
- * drawn, including Ajax data loaded, if Ajax data is required.
14968
- * @name DataTable#init.dt
14969
- * @event
14970
- * @param {event} e jQuery event object
14971
- * @param {object} oSettings DataTables settings object
14972
- * @param {object} json The JSON object request from the server - only
14973
- * present if client-side Ajax sourced data is used</li></ol>
14974
- */
14975
-
14976
- /**
14977
- * State save event, fired when the table has changed state a new state save
14978
- * is required. This event allows modification of the state saving object
14979
- * prior to actually doing the save, including addition or other state
14980
- * properties (for plug-ins) or modification of a DataTables core property.
14981
- * @name DataTable#stateSaveParams.dt
14982
- * @event
14983
- * @param {event} e jQuery event object
14984
- * @param {object} oSettings DataTables settings object
14985
- * @param {object} json The state information to be saved
14986
- */
14987
-
14988
- /**
14989
- * State load event, fired when the table is loading state from the stored
14990
- * data, but prior to the settings object being modified by the saved state
14991
- * - allowing modification of the saved state is required or loading of
14992
- * state for a plug-in.
14993
- * @name DataTable#stateLoadParams.dt
14994
- * @event
14995
- * @param {event} e jQuery event object
14996
- * @param {object} oSettings DataTables settings object
14997
- * @param {object} json The saved state information
14998
- */
14999
-
15000
- /**
15001
- * State loaded event, fired when state has been loaded from stored data and
15002
- * the settings object has been modified by the loaded data.
15003
- * @name DataTable#stateLoaded.dt
15004
- * @event
15005
- * @param {event} e jQuery event object
15006
- * @param {object} oSettings DataTables settings object
15007
- * @param {object} json The saved state information
15008
- */
15009
-
15010
- /**
15011
- * Processing event, fired when DataTables is doing some kind of processing
15012
- * (be it, order, searcg or anything else). It can be used to indicate to
15013
- * the end user that there is something happening, or that something has
15014
- * finished.
15015
- * @name DataTable#processing.dt
15016
- * @event
15017
- * @param {event} e jQuery event object
15018
- * @param {object} oSettings DataTables settings object
15019
- * @param {boolean} bShow Flag for if DataTables is doing processing or not
15020
- */
15021
-
15022
- /**
15023
- * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15024
- * request to made to the server for new data. This event is called before
15025
- * DataTables processed the returned data, so it can also be used to pre-
15026
- * process the data returned from the server, if needed.
15027
- *
15028
- * Note that this trigger is called in `fnServerData`, if you override
15029
- * `fnServerData` and which to use this event, you need to trigger it in you
15030
- * success function.
15031
- * @name DataTable#xhr.dt
15032
- * @event
15033
- * @param {event} e jQuery event object
15034
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15035
- * @param {object} json JSON returned from the server
15036
- *
15037
- * @example
15038
- * // Use a custom property returned from the server in another DOM element
15039
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15040
- * $('#status').html( json.status );
15041
- * } );
15042
- *
15043
- * @example
15044
- * // Pre-process the data returned from the server
15045
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15046
- * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15047
- * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15048
- * }
15049
- * // Note no return - manipulate the data directly in the JSON object.
15050
- * } );
15051
- */
15052
-
15053
- /**
15054
- * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15055
- * or passing the bDestroy:true parameter in the initialisation object. This
15056
- * can be used to remove bound events, added DOM nodes, etc.
15057
- * @name DataTable#destroy.dt
15058
- * @event
15059
- * @param {event} e jQuery event object
15060
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15061
- */
15062
-
15063
- /**
15064
- * Page length change event, fired when number of records to show on each
15065
- * page (the length) is changed.
15066
- * @name DataTable#length.dt
15067
- * @event
15068
- * @param {event} e jQuery event object
15069
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15070
- * @param {integer} len New length
15071
- */
15072
-
15073
- /**
15074
- * Column sizing has changed.
15075
- * @name DataTable#column-sizing.dt
15076
- * @event
15077
- * @param {event} e jQuery event object
15078
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15079
- */
15080
-
15081
- /**
15082
- * Column visibility has changed.
15083
- * @name DataTable#column-visibility.dt
15084
- * @event
15085
- * @param {event} e jQuery event object
15086
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15087
- * @param {int} column Column index
15088
- * @param {bool} vis `false` if column now hidden, or `true` if visible
15089
- */
15090
-
15091
- return $.fn.dataTable;
15092
- }));
15093
-
15094
- }(window, document));
15095
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/dependencies/datatables/js/jquery.dataTables.min.js DELETED
@@ -1,163 +0,0 @@
1
- /*!
2
- DataTables 1.10.8
3
- ©2008-2014 SpryMedia Ltd - datatables.net/license
4
- */
5
- (function(Fa,T,k){var S=function(g){function X(a){var b,c,d={};g.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;g.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),g.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)&&db(a)}function eb(a){B(a,"ordering","bSort");B(a,"orderMulti","bSortMulti");B(a,"orderClasses","bSortClasses");B(a,"orderCellsTop","bSortCellsTop");B(a,"order","aaSorting");B(a,"orderFixed","aaSortingFixed");B(a,"paging","bPaginate");
7
- B(a,"pagingType","sPaginationType");B(a,"pageLength","iDisplayLength");B(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 fb(a){B(a,"orderable","bSortable");B(a,"orderData","aDataSort");B(a,"orderSequence","asSorting");B(a,"orderDataType","sortDataType");var b=a.aDataSort;b&&!g.isArray(b)&&(a.aDataSort=[b])}function gb(a){var a=a.oBrowser,b=g("<div/>").css({position:"fixed",
8
- top:0,left:0,height:1,width:1,overflow:"hidden"}).append(g("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(g('<div class="test"/>').css({width:"100%",height:10}))).appendTo("body"),c=b.find(".test");a.bScrollOversize=100===c[0].offsetWidth;a.bScrollbarLeft=1!==Math.round(c.offset().left);a.bBounding=b[0].getBoundingClientRect().width?!0:!1;b.remove()}function hb(a,b,c,d,e,f){var h,i=!1;c!==k&&(h=c,i=!0);for(;d!==e;)a.hasOwnProperty(d)&&(h=i?b(h,a[d],d,a):a[d],
9
- i=!0,d+=f);return h}function Ga(a,b){var c=m.defaults.column,d=a.aoColumns.length,c=g.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]=g.extend({},m.models.oSearch,c[d]);ka(a,d,g(b).data())}function ka(a,b,c){var b=a.aoColumns[b],d=a.oClasses,e=g(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);
10
- f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(fb(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),g.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var h=b.mData,i=P(h),j=b.mRender?P(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=g.isPlainObject(h)&&(c(h.sort)||c(h.type)||c(h.filter));b.fnGetData=
11
- 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(h)(a,b,c)};"number"!==typeof h&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==g.inArray("asc",b.asSorting);c=-1!==g.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=
12
- 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 la(a,b){var c=$(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function aa(a,b){var c=$(a,"bVisible"),c=g.inArray(b,c);return-1!==c?c:null}function ba(a){return $(a,"bVisible").length}function $(a,b){var c=
13
- [];g.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,h,i,j,g,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){h=0;for(i=d.length;h<i;h++){j=0;for(g=c.length;j<g;j++){q[j]===k&&(q[j]=y(a,j,e,"type"));r=d[h](q[j],a);if(!r&&h!==d.length-1)break;if("html"===r)break}if(r){l.sType=r;break}}l.sType||(l.sType="string")}}function ib(a,b,c,d){var e,f,h,i,j,n,l=a.aoColumns;
14
- if(b)for(e=b.length-1;0<=e;e--){n=b[e];var r=n.targets!==k?n.targets:n.aTargets;g.isArray(r)||(r=[r]);f=0;for(h=r.length;f<h;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;for(j=l.length;i<j;i++)("_all"==r[f]||g(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=g.extend(!0,{},m.models.oRow,{src:c?"dom":
15
- "data",idx:e});f._aData=b;a.aoData.push(f);for(var h=a.aoColumns,i=0,j=h.length;i<j;i++)c&&Ja(a,e,i,y(a,e,i)),h[i].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ka(a,e,c,d);return e}function ma(a,b){var c;b instanceof g||(b=g(b));return b.map(function(b,e){c=na(a,e);return L(a,c.data,e,c.cells)})}function y(a,b,c,d){var e=a.iDraw,f=a.aoColumns[c],h=a.aoData[b]._aData,i=f.sDefaultContent,c=f.fnGetData(h,d,{settings:a,row:b,col:c});if(c===k)return a.iDrawError!=
16
- 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===h||null===c)&&null!==i)c=i;else if("function"===typeof c)return c.call(h);return null===c&&"display"==d?"":c}function Ja(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}function La(a){return g.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\./g,".")})}function P(a){if(g.isPlainObject(a)){var b={};
17
- g.each(a,function(a,c){c&&(b[a]=P(c))});return function(a,c,f,h){var i=b[c]||b._;return i!==k?i(a,c,f,h):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,h){return a(b,c,f,h)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,f){var h,i;if(""!==f){i=La(f);for(var j=0,g=i.length;j<g;j++){f=i[j].match(ca);h=i[j].match(U);if(f){i[j]=i[j].replace(ca,"");""!==i[j]&&(a=a[i[j]]);h=[];i.splice(0,j+1);i=i.join(".");
18
- j=0;for(g=a.length;j<g;j++)h.push(c(a[j],b,i));a=f[0].substring(1,f[0].length-1);a=""===a?h:h.join(a);break}else if(h){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(g.isPlainObject(a))return Q(a._);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("[")||
19
- -1!==a.indexOf("("))){var b=function(a,d,e){var e=La(e),f;f=e[e.length-1];for(var h,i,j=0,g=e.length-1;j<g;j++){h=e[j].match(ca);i=e[j].match(U);if(h){e[j]=e[j].replace(ca,"");a[e[j]]=[];f=e.slice();f.splice(0,j+1);h=f.join(".");i=0;for(g=d.length;i<g;i++)f={},b(f,d[i],h),a[e[j]].push(f);return}i&&(e[j]=e[j].replace(U,""),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(ca,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,
20
- d){b[a]=d}}function Ma(a){return D(a.aoData,"_aData")}function oa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0}function pa(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 da(a,b,c,d){var e=a.aoData[b],f,h=function(c,f){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=y(a,b,f,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=na(a,e,d,d===k?k:e._aData).data;else{var i=e.anCells;if(i)if(d!==
21
- k)h(i[d],d);else{c=0;for(f=i.length;c<f;c++)h(i[c],c)}}e._aSortData=null;e._aFilterData=null;h=a.aoColumns;if(d!==k)h[d].sType=null;else{c=0;for(f=h.length;c<f;c++)h[c].sType=null;Na(a,e)}}function na(a,b,c,d){var e=[],f=b.firstChild,h,i,j=0,n,l=a.aoColumns,r=a._rowReadObject,d=d||r?{}:[],q=function(a,b){if("string"===typeof a){var c=a.indexOf("@");-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=g.trim(a.innerHTML),i&&i._bAttrSrc?(Q(i.mData._)(d,n),
22
- 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;){h=f.nodeName.toUpperCase();if("TD"==h||"TH"==h)jb(f),e.push(f);f=f.nextSibling}else{e=b.anCells;f=0;for(h=e.length;f<h;f++)jb(e[f])}(b=b.getAttribute("id"))&&Q(a.rowId)(d,b);return{data:d,cells:e}}function Ka(a,b,c,d){var e=a.aoData[b],f=e._aData,h=[],i,j,g,l,r;if(null===e.nTr){i=c||T.createElement("tr");e.nTr=i;e.anCells=h;i._DT_RowIndex=b;Na(a,e);l=0;for(r=a.aoColumns.length;l<
23
- r;l++){g=a.aoColumns[l];j=c?d[l]:T.createElement(g.sCellType);h.push(j);if(!c||g.mRender||g.mData!==l)j.innerHTML=y(a,b,l,"display");g.sClass&&(j.className+=" "+g.sClass);g.bVisible&&!c?i.appendChild(j):!g.bVisible&&c&&j.parentNode.removeChild(j);g.fnCreatedCell&&g.fnCreatedCell.call(a.oInstance,j,y(a,b,l),f,b,l)}w(a,"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(" "),
24
- b.__rowc=b.__rowc?Oa(b.__rowc.concat(e)):e,g(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&g(c).attr(d.DT_RowAttr);d.DT_RowData&&g(c).data(d.DT_RowData)}}function kb(a){var b,c,d,e,f,h=a.nTHead,i=a.nTFoot,j=0===g("th, td",h).length,n=a.oClasses,l=a.aoColumns;j&&(e=g("<tr/>").appendTo(h));b=0;for(c=l.length;b<c;b++)f=l[b],d=g(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",
25
- a.sTableId),Pa(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Qa(a,"header")(a,d,f,n);j&&ea(a.aoHeader,h);g(h).find(">tr").attr("role","row");g(h).find(">tr>th, >tr>td").addClass(n.sHeaderTH);g(i).find(">tr>th, >tr>td").addClass(n.sFooterTH);if(null!==i){a=a.aoFooter[0];b=0;for(c=a.length;b<c;b++)f=l[b],f.nTf=a[b].cell,f.sClass&&g(f.nTf).addClass(f.sClass)}}function fa(a,b,c){var d,e,f,h=[],i=[],j=a.aoColumns.length,n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){h[d]=b[d].slice();h[d].nTr=
26
- b[d].nTr;for(f=j-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&h[d].splice(f,1);i.push([])}d=0;for(e=h.length;d<e;d++){if(a=h[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=h[d].length;f<b;f++)if(n=j=1,i[d][f]===k){a.appendChild(h[d][f].cell);for(i[d][f]=1;h[d+j]!==k&&h[d][f].cell==h[d+j][f].cell;)i[d+j][f]=1,j++;for(;h[d][f+n]!==k&&h[d][f].cell==h[d][f+n].cell;){for(c=0;c<j;c++)i[d+c][f+n]=1;n++}g(h[d][f].cell).attr("rowspan",j).attr("colspan",n)}}}}function M(a){var b=w(a,"aoPreDrawCallback",
27
- "preDraw",[a]);if(-1!==g.inArray(!1,b))C(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,h=a.iInitDisplayStart,i="ssp"==z(a),j=a.aiDisplay;a.bDrawing=!0;h!==k&&-1!==h&&(a._iDisplayStart=i?h:h>=a.fnRecordsDisplay()?0:h,a.iInitDisplayStart=-1);var h=a._iDisplayStart,n=a.fnDisplayEnd();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:h;i<f;i++){var l=j[i],r=a.aoData[l];
28
- null===r.nTr&&Ka(a,l);l=r.nTr;if(0!==e){var q=d[c%e];r._sRowStripe!=q&&(g(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"==z(a)?c=f.sLoadingRecords:f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),b[0]=g("<tr/>",{"class":e?d[0]:""}).append(g("<td />",{valign:"top",colSpan:ba(a),"class":a.oClasses.sRowEmpty}).html(c))[0];w(a,"aoHeaderCallback","header",[g(a.nTHead).children("tr")[0],
29
- Ma(a),h,n,j]);w(a,"aoFooterCallback","footer",[g(a.nTFoot).children("tr")[0],Ma(a),h,n,j]);d=g(a.nTBody);d.children().detach();d.append(g(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?ga(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;M(a);a._drawHold=!1}function nb(a){var b=a.oClasses,c=g(a.nTable),c=g("<div/>").insertBefore(c),d=a.oFeatures,e=g("<div/>",
30
- {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(""),h,i,j,n,l,r,q=0;q<f.length;q++){h=null;i=f[q];if("<"==i){j=g("<div/>")[0];n=f[q+1];if("'"==n||'"'==n){l="";for(r=2;f[q+r]!=n;)l+=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-
31
- 1):j.className=l;q+=r}e.append(j);e=g(j)}else if(">"==i)e=e.parent();else if("l"==i&&d.bPaginate&&d.bLengthChange)h=ob(a);else if("f"==i&&d.bFilter)h=pb(a);else if("r"==i&&d.bProcessing)h=qb(a);else if("t"==i)h=rb(a);else if("i"==i&&d.bInfo)h=sb(a);else if("p"==i&&d.bPaginate)h=tb(a);else if(0!==m.ext.feature.length){j=m.ext.feature;r=0;for(n=j.length;r<n;r++)if(i==j[r].cFeature){h=j[r].fnInit(a);break}}h&&(j=a.aanFeatures,j[i]||(j[i]=[]),j[i].push(h),e.append(h))}c.replaceWith(e);a.nHolding=null}
32
- function ea(a,b){var c=g(b).children("tr"),d,e,f,h,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||1===l?1:l;r=!r||0===r||1===r?1:r;h=0;for(i=a[f];i[h];)h++;n=h;q=1===l?!0:!1;for(i=0;i<l;i++)for(h=0;h<r;h++)a[f+h][n+i]={cell:e,unique:q},a[f+h].nTr=d}e=e.nextSibling}}}function qa(a,
33
- b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],ea(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,h=c[b].length;f<h;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&&g.isArray(b)){var d={},e=/(.*?)\[\]$/;g.each(b,function(a,b){var c=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,h=a.ajax,i=a.oInstance,j=function(b){w(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(g.isPlainObject(h)&&
34
- h.data){f=h.data;var n=g.isFunction(f)?f(b,a):f,b=g.isFunction(f)&&n?n:g.extend(!0,b,n);delete h.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 f=w(a,null,"xhr",[a,null,a.jqXHR]);-1===g.inArray(!0,f)&&("parsererror"==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,
35
- g.map(b,function(a,b){return{name:b,value:a}}),j,a):a.sAjaxSource||"string"===typeof h?a.jqXHR=g.ajax(g.extend(n,{url:h||a.sAjaxSource})):g.isFunction(h)?a.jqXHR=h.call(i,b,j,a):(a.jqXHR=g.ajax(g.extend(n,h)),h.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=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,h,i=[],j,n,l,r=V(a);h=a._iDisplayStart;j=!1!==d.bPaginate?a._iDisplayLength:-1;var q=function(a,
36
- b){i.push({name:a,value:b})};q("sEcho",a.iDraw);q("iColumns",c);q("sColumns",D(b,"sName").join(","));q("iDisplayStart",h);q("iDisplayLength",j);var k={draw:a.iDraw,columns:[],order:[],start:h,length:j,search:{value:e.sSearch,regex:e.bRegex}};for(h=0;h<c;h++)n=b[h],l=f[h],j="function"==typeof n.mData?"function":n.mData,k.columns.push({data:j,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:l.sSearch,regex:l.bRegex}}),q("mDataProp_"+h,j),d.bFilter&&(q("sSearch_"+h,l.sSearch),
37
- q("bRegex_"+h,l.bRegex),q("bSearchable_"+h,n.bSearchable)),d.bSort&&q("bSortable_"+h,n.bSortable);d.bFilter&&(q("sSearch",e.sSearch),q("bRegex",e.bRegex));d.bSort&&(g.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?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!==
38
- k?b.iTotalDisplayRecords:b.recordsFiltered;if(d){if(1*d<a.iDraw)return;a.iDraw=1*d}oa(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=g.isPlainObject(a.ajax)&&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,
39
- e=a.oPreviousSearch,f=a.aanFeatures,h='<input type="search" class="'+b.sFilterInput+'"/>',i=d.sSearch,i=i.match(/_INPUT_/)?i.replace("_INPUT_",h):i+h,b=g("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(g("<label/>").append(i)),f=function(){var b=!this.value?"":this.value;b!=e.sSearch&&(ga(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,M(a))},h=null!==a.searchDelay?a.searchDelay:"ssp"===z(a)?400:0,j=g("input",b).val(e.sSearch).attr("placeholder",
40
- d.sSearchPlaceholder).bind("keyup.DT search.DT input.DT paste.DT cut.DT",h?ua(f,h):f).bind("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);g(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{j[0]!==T.activeElement&&j.val(e.sSearch)}catch(f){}});return b[0]}function ga(a,b,c){var d=a.oPreviousSearch,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"!=z(a)){wb(a,b.sSearch,
41
- 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,h=b.length;f<h;f++){for(var i=[],j=0,g=c.length;j<g;j++)e=c[j],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,j)&&i.push(e);c.length=0;c.push.apply(c,i)}}function xb(a,b,c,d,e,
42
- f){if(""!==b)for(var h=a.aiDisplay,d=Ra(b,d,e,f),e=h.length-1;0<=e;e--)b=a.aoData[h[e]]._aFilterData[c],d.test(b)||h.splice(e,1)}function wb(a,b,c,d,e,f){var d=Ra(b,d,e,f),e=a.oPreviousSearch.sSearch,f=a.aiDisplayMaster,h;0!==m.ext.search.length&&(c=!0);h=zb(a);if(0>=b.length)a.aiDisplay=f.slice();else{if(h||c||e.length>b.length||0!==b.indexOf(e)||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 Ra(a,b,c,d){a=b?a:va(a);
43
- c&&(a="^(?=.*?"+g.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(Zb,"\\$1")}function zb(a){var b=a.aoColumns,c,d,e,f,h,i,j,g,l=m.ext.type.search;c=!1;d=0;for(f=a.aoData.length;d<f;d++)if(g=a.aoData[d],!g._aFilterData){i=[];e=0;for(h=b.length;e<h;e++)c=b[e],c.bSearchable?(j=y(a,d,e,"filter"),l[c.sType]&&(j=l[c.sType](j)),null===j&&(j=
44
- ""),"string"!==typeof j&&j.toString&&(j=j.toString())):j="",j.indexOf&&-1!==j.indexOf("&")&&(wa.innerHTML=j,j=$b?wa.textContent:wa.innerText),j.replace&&(j=j.replace(/[\r\n]/g,"")),i.push(j);g._aFilterData=i;g._sFilterRow=i.join(" ");c=!0}return c}function Ab(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}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,
45
- d=g("<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"),g(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(),h=a.fnRecordsDisplay(),i=h?c.sInfo:c.sInfoEmpty;h!==f&&(i+=" "+c.sInfoFiltered);i+=c.sInfoPostFix;i=Db(a,i);c=c.fnInfoCallback;null!==c&&(i=
46
- c.call(a.oInstance,a,d,e,f,h,i));g(b).html(i)}}function Db(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),h=-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,h?1:Math.ceil(d/e))).replace(/_PAGES_/g,c.call(a,h?1:Math.ceil(f/e)))}function ha(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var h=
47
- a.bDeferLoading;if(a.bInitialised){nb(a);kb(a);fa(a,a.aoHeader);fa(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=z(a);if("ssp"!=e||h)"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),ta(a))}else setTimeout(function(){ha(a)},200)}function ta(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Y(a);w(a,"aoInitComplete","init",
48
- [a,b])}function Sa(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Ta(a);w(a,null,"length",[a,c])}function ob(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=g.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=g("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),h=0,i=f.length;h<i;h++)e[0][h]=new Option(d[h],f[h]);var j=g("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(j[0].id=c+"_length");j.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));g("select",
49
- j).val(a._iDisplayLength).bind("change.DT",function(){Sa(a,g(this).val());M(a)});g(a.nTable).bind("length.dt.DT",function(b,c,f){a===c&&g("select",j).val(f)});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=g("<div/>").addClass(a.oClasses.sPaging+b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,g=a._iDisplayLength,n=a.fnRecordsDisplay(),l=-1===
50
- g,b=l?0:Math.ceil(b/g),g=l?1:Math.ceil(n/g),n=c(b,g),k,l=0;for(k=f.p.length;l<k;l++)Qa(a,"pageButton")(a,f.p[l],l,n,b,g)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Ua(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"==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=
51
- d;b&&(w(a,null,"page",[a]),c&&M(a));return b}function qb(a){return g("<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&&g(a.aanFeatures.r).css("display",b?"block":"none");w(a,null,"processing",[a,b])}function rb(a){var b=g(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,h=b.children("caption"),
52
- i=h.length?h[0]._captionSide:null,j=g(b[0].cloneNode(!1)),n=g(b[0].cloneNode(!1)),l=b.children("tfoot");c.sX&&"100%"===b.attr("width")&&b.removeAttr("width");l.length||(l=null);j=g("<div/>",{"class":f.sScrollWrapper}).append(g("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:u(d):"100%"}).append(g("<div/>",{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(j.removeAttr("id").css("margin-left",0).append("top"===
53
- i?h:null).append(b.children("thead"))))).append(g("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:u(d)}).append(b));l&&j.append(g("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:u(d):"100%"}).append(g("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",0).append("bottom"===i?h:null).append(b.children("tfoot")))));var b=j.children(),k=b[0],f=b[1],q=l?b[2]:null;if(d)g(f).on("scroll.DT",function(){var a=
54
- this.scrollLeft;k.scrollLeft=a;l&&(q.scrollLeft=a)});g(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=g(a.nScrollHead),h=f[0].style,i=f.children("div"),j=i[0].style,n=i.children("table"),i=a.nScrollBody,l=g(i),k=i.style,q=g(a.nScrollFoot).children("div"),m=q.children("table"),o=g(a.nTHead),E=g(a.nTable),p=E[0],t=p.style,
55
- N=a.nTFoot?g(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%");g.each(qa(a,x),function(b,c){B=la(a,b);c.style.width=a.aoColumns[B].sWidth});
56
- 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(g(a).css("width")))},v);H(function(a,b){a.style.width=y[b]},o);g(v).height(0);N&&(H(C,O),H(function(a){z.push(u(g(a).css("width")))},O),H(function(a,b){a.style.width=z[b]},s),g(O).height(0));H(function(a,
57
- 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=u(s);h.width=u(s);N&&(a.nScrollFoot.style.width=u(s));!e&&w&&(k.height=
58
- 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,h,i;e<f;){h=b[e].firstChild;for(i=c?c[e].firstChild:null;h;)1===h.nodeType&&(c?a(h,i,d):a(h,d),d++),h=h.nextSibling,
59
- 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,h=d.sXInner,i=c.length,j=$(a,"bVisible"),n=g("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==ba(a)&&i==n.length)for(m=0;m<i;m++)c[m].sWidth=u(n.eq(m).width());else{i=g(b).clone().css("visibility","hidden").removeAttr("id");
60
- i.find("tbody tr").remove();var t=g("<tr/>").appendTo(i.find("tbody"));i.find("thead, tfoot").remove();i.append(g(a.nTHead).clone()).append(g(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],g(Gb(a,q)).clone(!1).append(o.sContentPadding).appendTo(t);q=g("<div/>").css(f||e?{position:"absolute",top:0,
61
- left:0,height:1,right:0,overflow:"hidden"}:{}).append(i).appendTo(k);f&&h?i.width(h):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=h=0;m<j.length;m++)o=c[j[m]],e=p.bBounding?n[m].getBoundingClientRect().width:g(n[m]).outerWidth(),h+=null===o.sWidthOrig?e:parseInt(o.sWidth,10)+e-g(n[m]).width();i.width(u(h));b.style.width=u(h)}for(m=0;m<j.length;m++)if(o=c[j[m]],p=g(n[m]).width())o.sWidth=u(p);b.style.width=u(i.css("width"));
62
- q.remove()}l&&(b.style.width=u(l));if((l||f)&&!a._reszEvt)b=function(){g(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,h=+new Date,i=arguments;d&&h<d+c?(clearTimeout(e),e=setTimeout(function(){d=k;a.apply(b,i)},c)):(d=h,a.apply(b,i))}}function Fb(a,b){if(!a)return 0;var c=g("<div/>").css("width",u(a)).appendTo(b||T.body),d=c[0].offsetWidth;c.remove();return d}function Gb(a,b){var c=
63
- Hb(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?g("<td/>").html(y(a,c,b,"display"))[0]:d.anCells[b]}function Hb(a,b){for(var c,d=-1,e=-1,f=0,h=a.aoData.length;f<h;f++)c=y(a,f,b,"display")+"",c=c.replace(ac,""),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 Ib(){var a=m.__scrollbarWidth;if(a===k){var b=g("<p/>").css({position:"absolute",top:0,left:0,width:"100%",height:150,padding:0,overflow:"scroll",
64
- visibility:"hidden"}).appendTo("body"),a=b[0].offsetWidth-b[0].clientWidth;m.__scrollbarWidth=a;b.remove()}return a}function V(a){var b,c,d=[],e=a.aoColumns,f,h,i,j;b=a.aaSortingFixed;c=g.isPlainObject(b);var n=[];f=function(a){a.length&&!g.isArray(a[0])?n.push(a):n.push.apply(n,a)};g.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++)h=f[b],i=e[h].sType||"string",n[a]._idx===k&&(n[a]._idx=g.inArray(n[a][1],
65
- e[h].asSorting)),d.push({src:j,col:h,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,h=0,i,g=a.aiDisplayMaster,n;Ia(a);n=V(a);b=0;for(c=n.length;b<c;b++)i=n[b],i.formatter&&h++,Jb(a,i.col);if("ssp"!=z(a)&&0!==n.length){b=0;for(c=g.length;b<c;b++)d[g[b]]=b;h===n.length?g.sort(function(a,b){var c,e,h,i,g=n.length,j=f[a]._aSortData,k=f[b]._aSortData;for(h=0;h<g;h++)if(i=n[h],c=j[i.col],e=k[i.col],c=c<e?-1:c>
66
- 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}):g.sort(function(a,b){var c,h,i,g,j=n.length,k=f[a]._aSortData,m=f[b]._aSortData;for(i=0;i<j;i++)if(g=n[i],c=k[g.col],h=m[g.col],g=e[g.type+"-"+g.dir]||e["string-"+g.dir],c=g(c,h),0!==c)return c;c=d[a];h=d[b];return c<h?-1:c>h?1:0})}a.bSorted=!0}function Kb(a){for(var b,c,d=a.aoColumns,e=V(a),a=a.oLanguage.oAria,f=0,h=d.length;f<h;f++){c=d[f];var i=c.asSorting;b=c.sTitle.replace(/<.*?>/g,"");var g=c.nTh;g.removeAttribute("aria-sort");
67
- c.bSortable&&(0<e.length&&e[0].col==f?(g.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:a.sSortDescending);g.setAttribute("aria-label",b)}}function Va(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,h=function(a,b){var c=a._idx;c===k&&(c=g.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=g.inArray(b,D(e,"0")),-1!==c?(b=h(e[c],!0),null===
68
- 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=h(e[0]),e.length=1,e[0][1]=f[b],e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);R(a);"function"==typeof d&&d(a)}function Pa(a,b,c,d){var e=a.aoColumns[c];Wa(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(C(a,!0),setTimeout(function(){Va(a,c,b.shiftKey,d);"ssp"!==z(a)&&C(a,!1)},0)):Va(a,c,b.shiftKey,d))})}function xa(a){var b=a.aLastSort,
69
- c=a.oClasses.sSortColumn,d=V(a),e=a.oFeatures,f,h;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)h=b[e].src,g(D(a.aoData,"anCells",h)).removeClass(c+(2>e?e+1:3));e=0;for(f=d.length;e<f;e++)h=d[e].src,g(D(a.aoData,"anCells",h)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Jb(a,b){var c=a.aoColumns[b],d=m.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,aa(a,b)));for(var f,h=m.ext.type.order[c.sType+"-pre"],i=0,g=a.aoData.length;i<g;i++)if(c=a.aoData[i],c._aSortData||(c._aSortData=
70
- []),!c._aSortData[b]||d)f=d?e[i]:y(a,i,b,"sort"),c._aSortData[b]=h?h(f):f}function ya(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:g.extend(!0,[],a.aaSorting),search:Ab(a.oPreviousSearch),columns:g.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 Lb(a){var b,c,d=
71
- 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===g.inArray(!1,b)&&(b=a.iStateDuration,!(0<b&&e.time<+new Date-1E3*b)&&d.length===e.columns.length))){a.oLoadedState=g.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=[],g.each(e.order,function(b,c){a.aaSorting.push(c[0]>=d.length?[0,c[1]]:
72
- c)}));e.search!==k&&g.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&&g.extend(a.aoPreSearchCols[b],Bb(f.search))}w(a,"aoStateLoaded","stateLoaded",[a,e])}}}function za(a){var b=m.settings,a=g.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/"+
73
- 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&&b(a,d,c)}}function F(a,b,c,d){g.isArray(c)?g.each(c,function(c,f){g.isArray(f)?F(a,b,f[0],f[1]):F(a,b,f)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Mb(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],g.isPlainObject(d)?(g.isPlainObject(a[e])||(a[e]={}),g.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==
74
- e&&g.isArray(d)?d.slice():d);return a}function Wa(a,b,c){g(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",function(){return!1})}function A(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function w(a,b,c,d){var e=[];b&&(e=g.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=g.Event(c+".dt"),g(a.nTable).trigger(b,d),e.push(b.result));return e}function Ta(a){var b=a._iDisplayStart,
75
- 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 Qa(a,b){var c=a.renderer,d=m.ext.renderer[b];return g.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||d._:d._}function z(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function Aa(a,b){var c=[],c=Nb.numbers_length,d=Math.floor(c/2);b<=c?c=W(0,b):a<=d?(c=W(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=W(b-(c-2),b):(c=W(a-d+2,a+d-1),c.push("ellipsis"),
76
- c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function db(a){g.each({num:function(b){return Ba(b,a)},"num-fmt":function(b){return Ba(b,a,Xa)},"html-num":function(b){return Ba(b,a,Ca)},"html-num-fmt":function(b){return Ba(b,a,Ca,Xa)}},function(b,c){v.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(v.type.search[b+a]=v.type.search.html)})}function Ob(a){return function(){var b=[za(this[m.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return m.ext.internal[a].apply(this,
77
- b)}}var m,v,t,p,s,Ya={},Pb=/[\r\n]/g,Ca=/<.*?>/g,bc=/^[\w\+\-]/,cc=/[\w\+\-]$/,Zb=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Xa=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi,K=function(a){return!a||!0===a||"-"===a?!0:!1},Qb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Rb=function(a,b){Ya[b]||(Ya[b]=RegExp(va(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(Ya[b],"."):a},Za=function(a,b,c){var d="string"===typeof a;
78
- if(K(a))return!0;b&&d&&(a=Rb(a,b));c&&d&&(a=a.replace(Xa,""));return!isNaN(parseFloat(a))&&isFinite(a)},Sb=function(a,b,c){return K(a)?!0:!(K(a)||"string"===typeof a)?null:Za(a.replace(Ca,""),b,c)?!0:null},D=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;e<f;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<f;e++)a[e]&&d.push(a[e][b]);return d},ia=function(a,b,c,d){var e=[],f=0,h=b.length;if(d!==k)for(;f<h;f++)a[b[f]][c]&&e.push(a[b[f]][c][d]);else for(;f<h;f++)e.push(a[b[f]][c]);return e},
79
- W=function(a,b){var c=[],d;b===k?(b=0,d=a):(d=b,b=a);for(var e=b;e<d;e++)c.push(e);return c},Tb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},Oa=function(a){var b=[],c,d,e=a.length,f,h=0;d=0;a:for(;d<e;d++){c=a[d];for(f=0;f<h;f++)if(b[f]===c)continue a;b.push(c);h++}return b},B=function(a,b,c){a[b]!==k&&(a[c]=a[b])},ca=/\[.*?\]$/,U=/\(\)$/,wa=g("<div>")[0],$b=wa.textContent!==k,ac=/<.*?>/g;m=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,
80
- b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new t(za(this[v.iApiIndex])):new t(this)};this.fnAddData=function(a,b){var c=this.api(!0),d=g.isArray(a)&&(g.isArray(a[0])||g.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&Z(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();
81
- (a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],g=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,g);(c===k||c)&&d.draw();return g};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,g){e=this.api(!0);null===b||b===k?e.search(a,c,d,g):e.column(b).search(a,c,d,g);e.draw()};this.fnGetData=function(a,b){var c=
82
- this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};
83
- this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return za(this[v.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var g=
84
- this.api(!0);c===k||null===c?g.row(b).data(a):g.cell(b,c).data(a);(e===k||e)&&g.columns.adjust();(d===k||d)&&g.draw();return 0};this.fnVersionCheck=v.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=v.internal;for(var e in m.ext.internal)e&&(this[e]=Ob(e));this.each(function(){var f={},f=1<d?Mb(f,a,!0):a,e=0,i,j=this.getAttribute("id"),n=!1,l=m.defaults,r=g(this);if("table"!=this.nodeName.toLowerCase())J(null,0,"Non-table node initialisation ("+this.nodeName+")",2);
85
- else{eb(l);fb(l.column);I(l,l,!0);I(l.column,l.column,!0);I(l,g.extend(f,r.data()));var q=m.settings,e=0;for(i=q.length;e<i;e++){var p=q[e];if(p.nTable==this||p.nTHead.parentNode==this||p.nTFoot&&p.nTFoot.parentNode==this){e=f.bRetrieve!==k?f.bRetrieve:l.bRetrieve;if(c||e)return p.oInstance;if(f.bDestroy!==k?f.bDestroy:l.bDestroy){p.oInstance.fnDestroy();break}else{J(p,0,"Cannot reinitialise DataTable",3);return}}if(p.sTableId==this.id){q.splice(e,1);break}}if(null===j||""===j)this.id=j="DataTables_Table_"+
86
- m.ext._unique++;var o=g.extend(!0,{},m.models.oSettings,{sDestroyWidth:r[0].style.width,sInstance:j,sTableId:j});o.nTable=this;o.oApi=b.internal;o.oInit=f;q.push(o);o.oInstance=1===b.length?b:r.dataTable();eb(f);f.oLanguage&&S(f.oLanguage);f.aLengthMenu&&!f.iDisplayLength&&(f.iDisplayLength=g.isArray(f.aLengthMenu[0])?f.aLengthMenu[0][0]:f.aLengthMenu[0]);f=Mb(g.extend(!0,{},l),f);F(o.oFeatures,f,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));
87
- F(o,f,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"],["bJQueryUI","bJUI"]]);F(o.oScroll,f,[["sScrollX","sX"],["sScrollXInner",
88
- "sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);F(o.oLanguage,f,"fnInfoCallback");A(o,"aoDrawCallback",f.fnDrawCallback,"user");A(o,"aoServerParams",f.fnServerParams,"user");A(o,"aoStateSaveParams",f.fnStateSaveParams,"user");A(o,"aoStateLoadParams",f.fnStateLoadParams,"user");A(o,"aoStateLoaded",f.fnStateLoaded,"user");A(o,"aoRowCallback",f.fnRowCallback,"user");A(o,"aoRowCreatedCallback",f.fnCreatedRow,"user");A(o,"aoHeaderCallback",f.fnHeaderCallback,"user");A(o,"aoFooterCallback",
89
- f.fnFooterCallback,"user");A(o,"aoInitComplete",f.fnInitComplete,"user");A(o,"aoPreDrawCallback",f.fnPreDrawCallback,"user");o.rowIdFn=P(f.rowId);j=o.oClasses;f.bJQueryUI?(g.extend(j,m.ext.oJUIClasses,f.oClasses),f.sDom===l.sDom&&"lfrtip"===l.sDom&&(o.sDom='<"H"lfr>t<"F"ip>'),o.renderer)?g.isPlainObject(o.renderer)&&!o.renderer.header&&(o.renderer.header="jqueryui"):o.renderer="jqueryui":g.extend(j,m.ext.classes,f.oClasses);r.addClass(j.sTable);if(""!==o.oScroll.sX||""!==o.oScroll.sY)o.oScroll.iBarWidth=
90
- Ib();o.iInitDisplayStart===k&&(o.iInitDisplayStart=f.iDisplayStart,o._iDisplayStart=f.iDisplayStart);null!==f.iDeferLoading&&(o.bDeferLoading=!0,e=g.isArray(f.iDeferLoading),o._iRecordsDisplay=e?f.iDeferLoading[0]:f.iDeferLoading,o._iRecordsTotal=e?f.iDeferLoading[1]:f.iDeferLoading);var t=o.oLanguage;g.extend(!0,t,f.oLanguage);""!==t.sUrl&&(g.ajax({dataType:"json",url:t.sUrl,success:function(a){S(a);I(l.oLanguage,a);g.extend(true,t,a);ha(o)},error:function(){ha(o)}}),n=!0);null===f.asStripeClasses&&
91
- (o.asStripeClasses=[j.sStripeOdd,j.sStripeEven]);var e=o.asStripeClasses,s=r.children("tbody").find("tr").eq(0);-1!==g.inArray(!0,g.map(e,function(a){return s.hasClass(a)}))&&(g("tbody tr",this).removeClass(e.join(" ")),o.asDestroyStripes=e.slice());q=[];e=this.getElementsByTagName("thead");0!==e.length&&(ea(o.aoHeader,e[0]),q=qa(o));if(null===f.aoColumns){p=[];e=0;for(i=q.length;e<i;e++)p.push(null)}else p=f.aoColumns;e=0;for(i=p.length;e<i;e++)Ga(o,q?q[e]:null);ib(o,f.aoColumnDefs,p,function(a,
92
- b){ka(o,a,b)});if(s.length){var u=function(a,b){return a.getAttribute("data-"+b)!==null?b:null};g.each(na(o,s[0]).cells,function(a,b){var c=o.aoColumns[a];if(c.mData===a){var d=u(b,"sort")||u(b,"order"),e=u(b,"filter")||u(b,"search");if(d!==null||e!==null){c.mData={_:a+".display",sort:d!==null?a+".@data-"+d:k,type:d!==null?a+".@data-"+d:k,filter:e!==null?a+".@data-"+e:k};ka(o,a)}}})}var v=o.oFeatures;f.bStateSave&&(v.bStateSave=!0,Lb(o,f),A(o,"aoDrawCallback",ya,"state_save"));if(f.aaSorting===k){q=
93
- o.aaSorting;e=0;for(i=q.length;e<i;e++)q[e][1]=o.aoColumns[e].asSorting[0]}xa(o);v.bSort&&A(o,"aoDrawCallback",function(){if(o.bSorted){var a=V(o),b={};g.each(a,function(a,c){b[c.src]=c.dir});w(o,null,"order",[o,a,b]);Kb(o)}});A(o,"aoDrawCallback",function(){(o.bSorted||z(o)==="ssp"||v.bDeferRender)&&xa(o)},"sc");gb(o);e=r.children("caption").each(function(){this._captionSide=r.css("caption-side")});i=r.children("thead");0===i.length&&(i=g("<thead/>").appendTo(this));o.nTHead=i[0];i=r.children("tbody");
94
- 0===i.length&&(i=g("<tbody/>").appendTo(this));o.nTBody=i[0];i=r.children("tfoot");if(0===i.length&&0<e.length&&(""!==o.oScroll.sX||""!==o.oScroll.sY))i=g("<tfoot/>").appendTo(this);0===i.length||0===i.children().length?r.addClass(j.sNoFooter):0<i.length&&(o.nTFoot=i[0],ea(o.aoFooter,o.nTFoot));if(f.aaData)for(e=0;e<f.aaData.length;e++)L(o,f.aaData[e]);else(o.bDeferLoading||"dom"==z(o))&&ma(o,g(o.nTBody).children("tr"));o.aiDisplay=o.aiDisplayMaster.slice();o.bInitialised=!0;!1===n&&ha(o)}});b=null;
95
- return this};var Ub=[],x=Array.prototype,dc=function(a){var b,c,d=m.settings,e=g.map(d,function(a){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=g.inArray(a,e),-1!==b?[d[b]]:null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=g(a):a instanceof g&&(c=a)}else return[];if(c)return c.map(function(){b=g.inArray(this,e);return-1!==b?d[b]:null}).toArray()};t=function(a,b){if(!(this instanceof t))return new t(a,
96
- b);var c=[],d=function(a){(a=dc(a))&&c.push.apply(c,a)};if(g.isArray(a))for(var e=0,f=a.length;e<f;e++)d(a[e]);else d(a);this.context=Oa(c);b&&this.push.apply(this,b.toArray?b.toArray():b);this.selector={rows:null,cols:null,opts:null};t.extend(this,this,Ub)};m.Api=t;t.prototype={any:function(){return 0!==this.count()},concat:x.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=
97
- this.context;return b.length>a?new t(b[a],this[a]):null},filter:function(a){var b=[];if(x.filter)b=x.filter.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new t(this.context,b)},flatten:function(){var a=[];return new t(this.context,a.concat.apply(a,this.toArray()))},join:x.join,indexOf:x.indexOf||function(a,b){for(var c=b||0,d=this.length;c<d;c++)if(this[c]===a)return c;return-1},iterator:function(a,b,c,d){var e=[],f,h,g,j,n,l=this.context,
98
- m,q,p=this.selector;"string"===typeof a&&(d=c,c=b,b=a,a=!1);h=0;for(g=l.length;h<g;h++){var o=new t(l[h]);if("table"===b)f=c.call(o,l[h],h),f!==k&&e.push(f);else if("columns"===b||"rows"===b)f=c.call(o,l[h],this[h],h),f!==k&&e.push(f);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){q=this[h];"column-rows"===b&&(m=Da(l[h],p.opts));j=0;for(n=q.length;j<n;j++)f=q[j],f="cell"===b?c.call(o,l[h],f.row,f.column,h,j):c.call(o,l[h],f,h,j,m),f!==k&&e.push(f)}}return e.length||d?(a=new t(l,a?
99
- e.concat.apply([],e):e),b=a.selector,b.rows=p.rows,b.cols=p.cols,b.opts=p.opts,a):this},lastIndexOf:x.lastIndexOf||function(a,b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(x.map)b=x.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new t(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:x.pop,push:x.push,reduce:x.reduce||function(a,b){return hb(this,a,b,0,this.length,
100
- 1)},reduceRight:x.reduceRight||function(a,b){return hb(this,a,b,this.length-1,-1,-1)},reverse:x.reverse,selector:null,shift:x.shift,sort:x.sort,splice:x.splice,toArray:function(){return x.slice.call(this)},to$:function(){return g(this)},toJQuery:function(){return g(this)},unique:function(){return new t(this.context,Oa(this))},unshift:x.unshift};t.extend=function(a,b,c){if(c.length&&b&&(b instanceof t||b.__dt_wrapper)){var d,e,f,h=function(a,b,c){return function(){var d=b.apply(a,arguments);t.extend(d,
101
- d,c.methodExt);return d}};d=0;for(e=c.length;d<e;d++)f=c[d],b[f.name]="function"===typeof f.val?h(a,f.val,f):g.isPlainObject(f.val)?{}:f.val,b[f.name].__dt_wrapper=!0,t.extend(a,b[f.name],f.propExt)}};t.register=p=function(a,b){if(g.isArray(a))for(var c=0,d=a.length;c<d;c++)t.register(a[c],b);else for(var e=a.split("."),f=Ub,h,i,c=0,d=e.length;c<d;c++){h=(i=-1!==e[c].indexOf("()"))?e[c].replace("()",""):e[c];var j;a:{j=0;for(var n=f.length;j<n;j++)if(f[j].name===h){j=f[j];break a}j=null}j||(j={name:h,
102
- val:{},methodExt:[],propExt:[]},f.push(j));c===d-1?j.val=b:f=i?j.methodExt:j.propExt}};t.registerPlural=s=function(a,b,c){t.register(a,c);t.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof t?a.length?g.isArray(a[0])?new t(a.context,a[0]):a[0]:k:a})};p("tables()",function(a){var b;if(a){b=t;var c=this.context;if("number"===typeof a)a=[c[a]];else var d=g.map(c,function(a){return a.nTable}),a=g(d).filter(a).map(function(){var a=g.inArray(this,d);return c[a]}).toArray();
103
- b=new b(a)}else b=this;return b});p("table()",function(a){var a=this.tables(a),b=a.context;return b.length?new t(b[0]):a});s("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});s("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},1)});s("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});s("tables().footer()","table().footer()",
104
- function(){return this.iterator("table",function(a){return a.nTFoot},1)});s("tables().containers()","table().container()",function(){return this.iterator("table",function(a){return a.nTableWrapper},1)});p("draw()",function(a){return this.iterator("table",function(b){"page"===a?M(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),R(b,!1===a))})});p("page()",function(a){return a===k?this.page.info().page:this.iterator("table",function(b){Ua(b,a)})});p("page.info()",function(){if(0===this.context.length)return k;
105
- var a=this.context[0],b=a._iDisplayStart,c=a._iDisplayLength,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:"ssp"===z(a)}});p("page.len()",function(a){return a===k?0!==this.context.length?this.context[0]._iDisplayLength:k:this.iterator("table",function(b){Sa(b,a)})});var Vb=function(a,b,c){if(c){var d=new t(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==
106
- z(a))R(a,b);else{C(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ra(a,[],function(c){oa(a);for(var c=sa(a,c),d=0,e=c.length;d<e;d++)L(a,c[d]);R(a,b);C(a,!1)})}};p("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});p("ajax.params()",function(){var a=this.context;if(0<a.length)return a[0].oAjaxData});p("ajax.reload()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});p("ajax.url()",function(a){var b=this.context;if(a===k){if(0===b.length)return k;
107
- b=b[0];return b.ajax?g.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){g.isPlainObject(b.ajax)?b.ajax.url=a:b.ajax=a})});p("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});var $a=function(a,b,c,d,e){var f=[],h,i,j,n,l,m;j=typeof b;if(!b||"string"===j||"function"===j||b.length===k)b=[b];j=0;for(n=b.length;j<n;j++){i=b[j]&&b[j].split?b[j].split(","):[b[j]];l=0;for(m=i.length;l<m;l++)(h=c("string"===typeof i[l]?
108
- g.trim(i[l]):i[l]))&&h.length&&f.push.apply(f,h)}a=v.selector[a];if(a.length){j=0;for(n=a.length;j<n;j++)f=a[j](d,e,f)}return f},ab=function(a){a||(a={});a.filter&&a.search===k&&(a.search=a.filter);return g.extend({search:"none",order:"current",page:"all"},a)},bb=function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Da=function(a,b){var c,d,e,f=[],h=a.aiDisplay;c=a.aiDisplayMaster;var i=b.search;d=b.order;
109
- e=b.page;if("ssp"==z(a))return"removed"===i?[]:W(0,c.length);if("current"==e){c=a._iDisplayStart;for(d=a.fnDisplayEnd();c<d;c++)f.push(h[c])}else if("current"==d||"applied"==d)f="none"==i?c.slice():"applied"==i?h.slice():g.map(c,function(a){return-1===g.inArray(a,h)?a:null});else if("index"==d||"original"==d){c=0;for(d=a.aoData.length;c<d;c++)"none"==i?f.push(c):(e=g.inArray(c,h),(-1===e&&"removed"==i||0<=e&&"applied"==i)&&f.push(c))}return f};p("rows()",function(a,b){a===k?a="":g.isPlainObject(a)&&
110
- (b=a,a="");var b=ab(b),c=this.iterator("table",function(c){var e=b;return $a("row",a,function(a){var b=Qb(a);if(b!==null&&!e)return[b];var i=Da(c,e);if(b!==null&&g.inArray(b,i)!==-1)return[b];if(!a)return i;if(typeof a==="function")return g.map(i,function(b){var e=c.aoData[b];return a(b,e._aData,e.nTr)?b:null});b=Tb(ia(c.aoData,i,"nTr"));if(a.nodeName&&g.inArray(a,b)!==-1)return[a._DT_RowIndex];if(typeof a==="string"&&a.charAt(0)==="#"){i=c.aIds[a.replace(/^#/,"")];if(i!==k)return[i.idx]}return g(b).filter(a).map(function(){return this._DT_RowIndex}).toArray()},
111
- c,e)},1);c.selector.rows=a;c.selector.opts=b;return c});p("rows().nodes()",function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||k},1)});p("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ia(a.aoData,b,"_aData")},1)});s("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){var d=b.aoData[c];return"search"===a?d._aFilterData:d._aSortData},1)});s("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",
112
- function(b,c){da(b,c,a)})});s("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});s("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var i=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+i)}return new t(c,b)});s("rows().remove()","row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData;e.splice(c,1);for(var f=0,g=e.length;f<
113
- g;f++)null!==e[f].nTr&&(e[f].nTr._DT_RowIndex=f);pa(b.aiDisplayMaster,c);pa(b.aiDisplay,c);pa(a[d],c,!1);Ta(b)});this.iterator("table",function(a){for(var c=0,d=a.aoData.length;c<d;c++)a.aoData[c].idx=c});return this});p("rows.add()",function(a){var b=this.iterator("table",function(b){var c,f,g,i=[];f=0;for(g=a.length;f<g;f++)c=a[f],c.nodeName&&"TR"===c.nodeName.toUpperCase()?i.push(ma(b,c)[0]):i.push(L(b,c));return i},1),c=this.rows(-1);c.pop();c.push.apply(c,b.toArray());return c});p("row()",function(a,
114
- b){return bb(this.rows(a,b))});p("row().data()",function(a){var b=this.context;if(a===k)return b.length&&this.length?b[0].aoData[this[0]]._aData:k;b[0].aoData[this[0]]._aData=a;da(b[0],this[0],"data");return this});p("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});p("row.add()",function(a){a instanceof g&&a.length&&(a=a[0]);var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?ma(b,a)[0]:L(b,a)});
115
- return this.row(b[0])});var cb=function(a,b){var c=a.context;if(c.length&&(c=c[0].aoData[b!==k?b:a[0]])&&c._details)c._details.remove(),c._detailsShow=k,c._details=k},Wb=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];if(d._details){(d._detailsShow=b)?d._details.insertAfter(d.nTr):d._details.detach();var e=c[0],f=new t(e),g=e.aoData;f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");0<D(g,"_details").length&&(f.on("draw.dt.DT_details",function(a,
116
- b){e===b&&f.rows({page:"current"}).eq(0).each(function(a){a=g[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),f.on("column-visibility.dt.DT_details",function(a,b){if(e===b)for(var c,d=ba(b),f=0,k=g.length;f<k;f++)c=g[f],c._details&&c._details.children("td[colspan]").attr("colspan",d)}),f.on("destroy.dt.DT_details",function(a,b){if(e===b)for(var c=0,d=g.length;c<d;c++)g[c]._details&&cb(f,c)}))}}};p("row().child()",function(a,b){var c=this.context;if(a===k)return c.length&&this.length?c[0].aoData[this[0]]._details:
117
- k;if(!0===a)this.child.show();else if(!1===a)cb(this);else if(c.length&&this.length){var d=c[0],c=c[0].aoData[this[0]],e=[],f=function(a,b){if(g.isArray(a)||a instanceof g)for(var c=0,k=a.length;c<k;c++)f(a[c],b);else a.nodeName&&"tr"===a.nodeName.toLowerCase()?e.push(a):(c=g("<tr><td/></tr>").addClass(b),g("td",c).addClass(b).html(a)[0].colSpan=ba(d),e.push(c[0]))};f(a,b);c._details&&c._details.remove();c._details=g(e);c._detailsShow&&c._details.insertAfter(c.nTr)}return this});p(["row().child.show()",
118
- "row().child().show()"],function(){Wb(this,!0);return this});p(["row().child.hide()","row().child().hide()"],function(){Wb(this,!1);return this});p(["row().child.remove()","row().child().remove()"],function(){cb(this);return this});p("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var ec=/^(.+):(name|visIdx|visible)$/,Xb=function(a,b,c,d,e){for(var c=[],d=0,f=e.length;d<f;d++)c.push(y(a,e[d],b));return c};p("columns()",
119
- function(a,b){a===k?a="":g.isPlainObject(a)&&(b=a,a="");var b=ab(b),c=this.iterator("table",function(c){var e=a,f=b,h=c.aoColumns,i=D(h,"sName"),j=D(h,"nTh");return $a("column",e,function(a){var b=Qb(a);if(a==="")return W(h.length);if(b!==null)return[b>=0?b:h.length+b];if(typeof a==="function"){var e=Da(c,f);return g.map(h,function(b,f){return a(f,Xb(c,f,0,0,e),j[f])?f:null})}var k=typeof a==="string"?a.match(ec):"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var m=
120
- g.map(h,function(a,b){return a.bVisible?b:null});return[m[m.length+b]]}return[la(c,b)];case "name":return g.map(i,function(a,b){return a===k[1]?b:null})}else return g(j).filter(a).map(function(){return g.inArray(this,j)}).toArray()},c,f)},1);c.selector.cols=a;c.selector.opts=b;return c});s("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});s("columns().footer()","column().footer()",function(){return this.iterator("column",
121
- function(a,b){return a.aoColumns[b].nTf},1)});s("columns().data()","column().data()",function(){return this.iterator("column-rows",Xb,1)});s("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});s("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ia(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});s("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",
122
- function(a,b,c,d,e){return ia(a.aoData,e,"anCells",b)},1)});s("columns().visible()","column().visible()",function(a,b){return this.iterator("column",function(c,d){if(a===k)return c.aoColumns[d].bVisible;var e=c.aoColumns,f=e[d],h=c.aoData,i,j,n;if(a!==k&&f.bVisible!==a){if(a){var l=g.inArray(!0,D(e,"bVisible"),d+1);i=0;for(j=h.length;i<j;i++)n=h[i].nTr,e=h[i].anCells,n&&n.insertBefore(e[d],e[l]||null)}else g(D(c.aoData,"anCells",d)).detach();f.bVisible=a;fa(c,c.aoHeader);fa(c,c.aoFooter);if(b===k||
123
- b)Y(c),(c.oScroll.sX||c.oScroll.sY)&&Z(c);w(c,null,"column-visibility",[c,d,a]);ya(c)}})});s("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===a?aa(b,c):c},1)});p("columns.adjust()",function(){return this.iterator("table",function(a){Y(a)},1)});p("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return la(c,b);if("fromData"===a||"toVisible"===a)return aa(c,b)}});p("column()",
124
- function(a,b){return bb(this.columns(a,b))});p("cells()",function(a,b,c){g.isPlainObject(a)&&(a.row===k?(c=a,a=null):(c=b,b=null));g.isPlainObject(b)&&(c=b,b=null);if(null===b||b===k)return this.iterator("table",function(b){var d=a,e=ab(c),f=b.aoData,h=Da(b,e),i=Tb(ia(f,h,"anCells")),j=g([].concat.apply([],i)),l,n=b.aoColumns.length,m,p,t,s,u,v;return $a("cell",d,function(a){var c=typeof a==="function";if(a===null||a===k||c){m=[];p=0;for(t=h.length;p<t;p++){l=h[p];for(s=0;s<n;s++){u={row:l,column:s};
125
- if(c){v=b.aoData[l];a(u,y(b,l,s),v.anCells?v.anCells[s]:null)&&m.push(u)}else m.push(u)}}return m}return g.isPlainObject(a)?[a]:j.filter(a).map(function(a,b){l=b.parentNode._DT_RowIndex;return{row:l,column:g.inArray(b,f[l].anCells)}}).toArray()},b,e)});var d=this.columns(b,c),e=this.rows(a,c),f,h,i,j,n,l=this.iterator("table",function(a,b){f=[];h=0;for(i=e[b].length;h<i;h++){j=0;for(n=d[b].length;j<n;j++)f.push({row:e[b][h],column:d[b][j]})}return f},1);g.extend(l.selector,{cols:b,rows:a,opts:c});
126
- return l});s("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b].anCells)?a[c]:k},1)});p("cells().data()",function(){return this.iterator("cell",function(a,b,c){return y(a,b,c)},1)});s("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});s("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return y(b,
127
- c,d,a)},1)});s("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,b,c){return{row:b,column:c,columnVisible:aa(a,c)}},1)});s("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){da(b,c,a,d)})});p("cell()",function(a,b,c){return bb(this.cells(a,b,c))});p("cell().data()",function(a){var b=this.context,c=this[0];if(a===k)return b.length&&c.length?y(b[0],c[0].row,c[0].column):k;Ja(b[0],c[0].row,c[0].column,a);da(b[0],c[0].row,
128
- "data",c[0].column);return this});p("order()",function(a,b){var c=this.context;if(a===k)return 0!==c.length?c[0].aaSorting:k;"number"===typeof a?a=[[a,b]]:g.isArray(a[0])||(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});p("order.listener()",function(a,b,c){return this.iterator("table",function(d){Pa(d,a,b,c)})});p(["columns().order()","column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];g.each(b[d],
129
- function(b,c){e.push([c,a])});c.aaSorting=e})});p("search()",function(a,b,c,d){var e=this.context;return a===k?0!==e.length?e[0].oPreviousSearch.sSearch:k:this.iterator("table",function(e){e.oFeatures.bFilter&&ga(e,g.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});s("columns().search()","column().search()",function(a,b,c,d){return this.iterator("column",function(e,f){var h=e.aoPreSearchCols;if(a===k)return h[f].sSearch;e.oFeatures.bFilter&&
130
- (g.extend(h[f],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),ga(e,e.oPreviousSearch,1))})});p("state()",function(){return this.context.length?this.context[0].oSavedState:null});p("state.clear()",function(){return this.iterator("table",function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});p("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null});p("state.save()",function(){return this.iterator("table",function(a){ya(a)})});
131
- m.versionCheck=m.fnVersionCheck=function(a){for(var b=m.version.split("."),a=a.split("."),c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};m.isDataTable=m.fnIsDataTable=function(a){var b=g(a).get(0),c=!1;g.each(m.settings,function(a,e){var f=e.nScrollHead?g("table",e.nScrollHead)[0]:null,h=e.nScrollFoot?g("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||h===b)c=!0});return c};m.tables=m.fnTables=function(a){var b=!1;g.isPlainObject(a)&&(b=
132
- a.api,a=a.visible);var c=g.map(m.settings,function(b){if(!a||a&&g(b.nTable).is(":visible"))return b.nTable});return b?new t(c):c};m.util={throttle:ua,escapeRegex:va};m.camelToHungarian=I;p("$()",function(a,b){var c=this.rows(b).nodes(),c=g(c);return g([].concat(c.filter(a).toArray(),c.find(a).toArray()))});g.each(["on","one","off"],function(a,b){p(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0].match(/\.dt\b/)||(a[0]+=".dt");var d=g(this.tables().nodes());d[b].apply(d,a);return this})});
133
- p("clear()",function(){return this.iterator("table",function(a){oa(a)})});p("settings()",function(){return new t(this.context,this.context)});p("init()",function(){var a=this.context;return a.length?a[0].oInit:null});p("data()",function(){return this.iterator("table",function(a){return D(a.aoData,"_aData")}).flatten()});p("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,f=b.nTBody,h=b.nTHead,i=b.nTFoot,j=g(e),f=g(f),
134
- k=g(b.nTableWrapper),l=g.map(b.aoData,function(a){return a.nTr}),p;b.bDestroying=!0;w(b,"aoDestroyCallback","destroy",[b]);a||(new t(b)).columns().visible(!0);k.unbind(".DT").find(":not(tbody *)").unbind(".DT");g(Fa).unbind(".DT-"+b.sInstance);e!=h.parentNode&&(j.children("thead").detach(),j.append(h));i&&e!=i.parentNode&&(j.children("tfoot").detach(),j.append(i));b.aaSorting=[];b.aaSortingFixed=[];xa(b);g(l).removeClass(b.asStripeClasses.join(" "));g("th, td",h).removeClass(d.sSortable+" "+d.sSortableAsc+
135
- " "+d.sSortableDesc+" "+d.sSortableNone);b.bJUI&&(g("th span."+d.sSortIcon+", td span."+d.sSortIcon,h).detach(),g("th, td",h).each(function(){var a=g("div."+d.sSortJUIWrapper,this);g(this).append(a.contents());a.detach()}));f.children().detach();f.append(l);h=a?"remove":"detach";j[h]();k[h]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),j.css("width",b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&f.children().each(function(a){g(this).addClass(b.asDestroyStripes[a%p])}));
136
- c=g.inArray(b,m.settings);-1!==c&&m.settings.splice(c,1)})});g.each(["column","row","cell"],function(a,b){p(b+"s().every()",function(a){return this.iterator(b,function(d,e,f,g,i){a.call((new t(d))[b](e,"cell"===b?f:k),e,f,g,i)})})});p("i18n()",function(a,b,c){var d=this.context[0],a=P(a)(d.oLanguage);a===k&&(a=b);c!==k&&g.isPlainObject(a)&&(a=a[c]!==k?a[c]:a._);return a.replace("%d",c)});m.version="1.10.8";m.settings=[];m.models={};m.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};
137
- m.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};m.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,
138
- sWidth:null,sWidthOrig:null};m.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,
139
- this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+
140
- "_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",
141
- sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:g.extend({},m.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};
142
- X(m.defaults);m.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};X(m.defaults.column);m.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,
143
- bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],
144
- aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],
145
- sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==z(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==z(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,
146
- b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};m.ext=v={buttons:{},classes:{},errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],
147
- search:{},order:{}},_unique:0,fnVersionCheck:m.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:m.version};g.extend(v,{afnFiltering:v.search,aTypes:v.type.detect,ofnSearch:v.type.search,oSort:v.type.order,afnSortData:v.order,aoFeatures:v.feature,oApi:v.internal,oStdClasses:v.classes,oPagination:v.pager});g.extend(m.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",
148
- sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",
149
- sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Ea="",Ea="",G=Ea+"ui-state-default",ja=Ea+"css_right ui-icon ui-icon-",Yb=Ea+"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";g.extend(m.ext.oJUIClasses,m.ext.classes,{sPageButton:"fg-button ui-button "+
150
- G,sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:G+" sorting_asc",sSortDesc:G+" sorting_desc",sSortable:G+" sorting",sSortableAsc:G+" sorting_asc_disabled",sSortableDesc:G+" sorting_desc_disabled",sSortableNone:G+" sorting_disabled",sSortJUIAsc:ja+"triangle-1-n",sSortJUIDesc:ja+"triangle-1-s",sSortJUI:ja+"carat-2-n-s",sSortJUIAscAllowed:ja+"carat-1-n",sSortJUIDescAllowed:ja+
151
- "carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead "+G,sScrollFoot:"dataTables_scrollFoot "+G,sHeaderTH:G,sFooterTH:G,sJUIHeader:Yb+" ui-corner-tl ui-corner-tr",sJUIFooter:Yb+" ui-corner-bl ui-corner-br"});var Nb=m.ext.pager;g.extend(Nb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[Aa(a,b)]},simple_numbers:function(a,b){return["previous",Aa(a,
152
- b),"next"]},full_numbers:function(a,b){return["first","previous",Aa(a,b),"next","last"]},_numbers:Aa,numbers_length:7});g.extend(!0,m.ext.renderer,{pageButton:{_:function(a,b,c,d,e,f){var h=a.oClasses,i=a.oLanguage.oPaginate,j,k,l=0,m=function(b,d){var p,q,t,s,u=function(b){Ua(a,b.data.action,true)};p=0;for(q=d.length;p<q;p++){s=d[p];if(g.isArray(s)){t=g("<"+(s.DT_el||"div")+"/>").appendTo(b);m(t,s)}else{j=null;k="";switch(s){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;
153
- case "first":j=i.sFirst;k=s+(e>0?"":" "+h.sPageButtonDisabled);break;case "previous":j=i.sPrevious;k=s+(e>0?"":" "+h.sPageButtonDisabled);break;case "next":j=i.sNext;k=s+(e<f-1?"":" "+h.sPageButtonDisabled);break;case "last":j=i.sLast;k=s+(e<f-1?"":" "+h.sPageButtonDisabled);break;default:j=s+1;k=e===s?h.sPageButtonActive:""}if(j!==null){t=g("<a>",{"class":h.sPageButton+" "+k,"aria-controls":a.sTableId,"data-dt-idx":l,tabindex:a.iTabIndex,id:c===0&&typeof s==="string"?a.sTableId+"_"+s:null}).html(j).appendTo(b);
154
- Wa(t,{action:s},u);l++}}}},p;try{p=g(b).find(T.activeElement).data("dt-idx")}catch(t){}m(g(b).empty(),d);p&&g(b).find("[data-dt-idx="+p+"]").focus()}}});g.extend(m.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return Za(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&(!bc.test(a)||!cc.test(a)))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||K(a)?"date":null},function(a,b){var c=b.oLanguage.sDecimal;return Za(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;
155
- return Sb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Sb(a,c,!0)?"html-num-fmt"+c:null},function(a){return K(a)||"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);g.extend(m.ext.type.search,{html:function(a){return K(a)?a:"string"===typeof a?a.replace(Pb," ").replace(Ca,""):""},string:function(a){return K(a)?a:"string"===typeof a?a.replace(Pb," "):a}});var Ba=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Rb(a,b));a.replace&&(c&&(a=a.replace(c,"")),
156
- d&&(a=a.replace(d,"")));return 1*a};g.extend(v.type.order,{"date-pre":function(a){return Date.parse(a)||0},"html-pre":function(a){return K(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return K(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,b){return a<b?1:a>b?-1:0}});db("");g.extend(!0,m.ext.renderer,{header:{_:function(a,b,c,d){g(a.nTable).on("order.dt.DT",function(e,
157
- f,g,i){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(i[e]=="asc"?d.sSortAsc:i[e]=="desc"?d.sSortDesc:c.sSortingClass)}})},jqueryui:function(a,b,c,d){g("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(g("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);g(a.nTable).on("order.dt.DT",function(e,f,g,i){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(i[e]=="asc"?d.sSortAsc:i[e]=="desc"?d.sSortDesc:c.sSortingClass);
158
- b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(i[e]=="asc"?d.sSortJUIAsc:i[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});m.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",f=Math.abs(parseFloat(f)),i=parseInt(f,10),f=c?b+(f-i).toFixed(c).substring(2):"";return g+(d||"")+i.toString().replace(/\B(?=(\d{3})+(?!\d))/g,
159
- a)+f+(e||"")}}}};g.extend(m.ext.internal,{_fnExternApiFunc:Ob,_fnBuildAjax:ra,_fnAjaxUpdate:lb,_fnAjaxParameters:ub,_fnAjaxUpdateDraw:vb,_fnAjaxDataSrc:sa,_fnAddColumn:Ga,_fnColumnOptions:ka,_fnAdjustColumnSizing:Y,_fnVisibleToColumnIndex:la,_fnColumnIndexToVisible:aa,_fnVisbleColumns:ba,_fnGetColumns:$,_fnColumnTypes:Ia,_fnApplyColumnDefs:ib,_fnHungarianMap:X,_fnCamelToHungarian:I,_fnLanguageCompat:S,_fnBrowserDetect:gb,_fnAddData:L,_fnAddTr:ma,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==
160
- k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return g.inArray(c,a.aoData[b].anCells)},_fnGetCellData:y,_fnSetCellData:Ja,_fnSplitObjNotation:La,_fnGetObjectDataFn:P,_fnSetObjectDataFn:Q,_fnGetDataMaster:Ma,_fnClearTable:oa,_fnDeleteIndex:pa,_fnInvalidate:da,_fnGetRowElements:na,_fnCreateTr:Ka,_fnBuildHead:kb,_fnDrawHead:fa,_fnDraw:M,_fnReDraw:R,_fnAddOptionsHtml:nb,_fnDetectHeader:ea,_fnGetUniqueThs:qa,_fnFeatureHtmlFilter:pb,_fnFilterComplete:ga,_fnFilterCustom:yb,_fnFilterColumn:xb,
161
- _fnFilter:wb,_fnFilterCreateSearch:Ra,_fnEscapeRegex:va,_fnFilterData:zb,_fnFeatureHtmlInfo:sb,_fnUpdateInfo:Cb,_fnInfoMacros:Db,_fnInitialise:ha,_fnInitComplete:ta,_fnLengthChange:Sa,_fnFeatureHtmlLength:ob,_fnFeatureHtmlPaginate:tb,_fnPageChange:Ua,_fnFeatureHtmlProcessing:qb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:rb,_fnScrollDraw:Z,_fnApplyToChildren:H,_fnCalculateColumnWidths:Ha,_fnThrottle:ua,_fnConvertToWidth:Fb,_fnGetWidestNode:Gb,_fnGetMaxLenString:Hb,_fnStringToCss:u,_fnScrollBarWidth:Ib,
162
- _fnSortFlatten:V,_fnSort:mb,_fnSortAria:Kb,_fnSortListener:Va,_fnSortAttachListener:Pa,_fnSortingClasses:xa,_fnSortData:Jb,_fnSaveState:ya,_fnLoadState:Lb,_fnSettingsFromNode:za,_fnLog:J,_fnMap:F,_fnBindAction:Wa,_fnCallbackReg:A,_fnCallbackFire:w,_fnLengthOverflow:Ta,_fnRenderer:Qa,_fnDataSource:z,_fnRowAttributes:Na,_fnCalculateEnd:function(){}});g.fn.dataTable=m;g.fn.dataTableSettings=m.settings;g.fn.dataTableExt=m.ext;g.fn.DataTable=function(a){return g(this).dataTable(a).api()};g.each(m,function(a,
163
- b){g.fn.DataTable[a]=b});return g.fn.dataTable};"function"===typeof define&&define.amd?define("datatables",["jquery"],S):"object"===typeof exports?module.exports=S(require("jquery")):jQuery&&!jQuery.fn.dataTable&&S(jQuery)})(window,document);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/dependencies/focusable/focus-element-overlay.min.js DELETED
@@ -1 +0,0 @@
1
- !function(e){function n(){o(),jQuery("body").prepend('<div id="overlay-layer"></div>'),p=jQuery("#overlay-layer"),h(),t()}function o(){jQuery.fn.focusable=function(e){return Focusable.setFocus(this,e),this}}function t(){p.on("click",".column",u),jQuery(window).on("resize",i),jQuery(window).on("keyup",d)}function i(){v&&(v=b.findOnResize?jQuery(v.selector):v,c())}function d(e){b.hideOnESC&&27===e.keyCode&&y&&a()}function u(){b.hideOnClick&&a()}function l(e,n){jQuery("body").css("overflow","hidden"),b=jQuery.extend(b,n),v=e,c(),p.fadeIn(b.fadeDuration)}function r(){p.find(".column").remove()}function a(){y=!1,v=null,jQuery("body").css("overflow",""),p.fadeOut(b.fadeDuration,r)}function c(){if(v){var e=0;for(y=!0,r();4>e;)f(e),e++}}function f(e){var n=v.offset(),o=0,t=0,i=s(v.outerWidth()),d="100%",u="";switch(e){case 0:i=s(n.left);break;case 1:t=s(n.left),d=s(n.top);break;case 2:t=s(n.left),o=s(v.outerHeight()+n.top);break;case 3:i="100%",t=s(v.outerWidth()+n.left)}u="top:"+o+";left:"+t+";width:"+i+";height:"+d,p.append('<div class="column" style="'+u+'"></div>')}function s(e){return e+"px"}function h(){var e=function(){var e=document.createElement("style");return e.appendChild(document.createTextNode("")),document.head.appendChild(e),e.sheet}();e.insertRule("#overlay-layer{ display:none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999; overflow: hidden; pointer-events: none; }",0),e.insertRule("#overlay-layer .column{ position: absolute; background: rgba(0,0,0,0.8); pointer-events: all; }",1)}var p=null,v=null,y=!1,b={fadeDuration:700,hideOnClick:!1,hideOnESC:!1,findOnResize:!1};jQuery(document).ready(n),e.Focusable={setFocus:l,hide:a,refresh:c}}(window);
 
assets/dependencies/index.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- //Nothing to see here
3
-
4
- header( 'HTTP/1.0 403 Forbidden' );
 
 
 
 
assets/dependencies/qtip/index.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- //Nothing to see here
3
-
4
- header( 'HTTP/1.0 403 Forbidden' );
 
 
 
 
assets/dependencies/qtip/jquery.qtip.min.js DELETED
@@ -1,21 +0,0 @@
1
- /*
2
- * jquery.qtip. The jQuery tooltip plugin
3
- *
4
- * Copyright (c) 2009 Craig Thompson
5
- * http://craigsworks.com
6
- *
7
- * Licensed under MIT
8
- * http://www.opensource.org/licenses/mit-license.php
9
- *
10
- * Launch : February 2009
11
- * Version : 1.0.0-rc3
12
- * Released: Tuesday 12th May, 2009 - 00:00
13
- * Debug: jquery.qtip.debug.js
14
- */
15
- (function(f){f.fn.qtip=function(B,u){var y,t,A,s,x,w,v,z;if(typeof B=="string"){if(typeof f(this).data("qtip")!=="object"){f.fn.qtip.log.error.call(self,1,f.fn.qtip.constants.NO_TOOLTIP_PRESENT,false)}if(B=="api"){return f(this).data("qtip").interfaces[f(this).data("qtip").current]}else{if(B=="interfaces"){return f(this).data("qtip").interfaces}}}else{if(!B){B={}}if(typeof B.content!=="object"||(B.content.jquery&&B.content.length>0)){B.content={text:B.content}}if(typeof B.content.title!=="object"){B.content.title={text:B.content.title}}if(typeof B.position!=="object"){B.position={corner:B.position}}if(typeof B.position.corner!=="object"){B.position.corner={target:B.position.corner,tooltip:B.position.corner}}if(typeof B.show!=="object"){B.show={when:B.show}}if(typeof B.show.when!=="object"){B.show.when={event:B.show.when}}if(typeof B.show.effect!=="object"){B.show.effect={type:B.show.effect}}if(typeof B.hide!=="object"){B.hide={when:B.hide}}if(typeof B.hide.when!=="object"){B.hide.when={event:B.hide.when}}if(typeof B.hide.effect!=="object"){B.hide.effect={type:B.hide.effect}}if(typeof B.style!=="object"){B.style={name:B.style}}B.style=c(B.style);s=f.extend(true,{},f.fn.qtip.defaults,B);s.style=a.call({options:s},s.style);s.user=f.extend(true,{},B)}return f(this).each(function(){if(typeof B=="string"){w=B.toLowerCase();A=f(this).qtip("interfaces");if(typeof A=="object"){if(u===true&&w=="destroy"){while(A.length>0){A[A.length-1].destroy()}}else{if(u!==true){A=[f(this).qtip("api")]}for(y=0;y<A.length;y++){if(w=="destroy"){A[y].destroy()}else{if(A[y].status.rendered===true){if(w=="show"){A[y].show()}else{if(w=="hide"){A[y].hide()}else{if(w=="focus"){A[y].focus()}else{if(w=="disable"){A[y].disable(true)}else{if(w=="enable"){A[y].disable(false)}}}}}}}}}}}else{v=f.extend(true,{},s);v.hide.effect.length=s.hide.effect.length;v.show.effect.length=s.show.effect.length;if(v.position.container===false){v.position.container=f(document.body)}if(v.position.target===false){v.position.target=f(this)}if(v.show.when.target===false){v.show.when.target=f(this)}if(v.hide.when.target===false){v.hide.when.target=f(this)}t=f.fn.qtip.interfaces.length;for(y=0;y<t;y++){if(typeof f.fn.qtip.interfaces[y]=="undefined"){t=y;break}}x=new d(f(this),v,t);f.fn.qtip.interfaces[t]=x;if(typeof f(this).data("qtip")=="object"){if(typeof f(this).attr("qtip")==="undefined"){f(this).data("qtip").current=f(this).data("qtip").interfaces.length}f(this).data("qtip").interfaces.push(x)}else{f(this).data("qtip",{current:0,interfaces:[x]})}if(v.content.prerender===false&&v.show.when.event!==false&&v.show.ready!==true){v.show.when.target.bind(v.show.when.event+".qtip-"+t+"-create",{qtip:t},function(C){z=f.fn.qtip.interfaces[C.data.qtip];z.options.show.when.target.unbind(z.options.show.when.event+".qtip-"+C.data.qtip+"-create");z.cache.mouse={x:C.pageX,y:C.pageY};p.call(z);z.options.show.when.target.trigger(z.options.show.when.event)})}else{x.cache.mouse={x:v.show.when.target.offset().left,y:v.show.when.target.offset().top};p.call(x)}}})};function d(u,t,v){var s=this;s.id=v;s.options=t;s.status={animated:false,rendered:false,disabled:false,focused:false};s.elements={target:u.addClass(s.options.style.classes.target),tooltip:null,wrapper:null,content:null,contentWrapper:null,title:null,button:null,tip:null,bgiframe:null};s.cache={mouse:{},position:{},toggle:0};s.timers={};f.extend(s,s.options.api,{show:function(y){var x,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"show")}if(s.elements.tooltip.css("display")!=="none"){return s}s.elements.tooltip.stop(true,false);x=s.beforeShow.call(s,y);if(x===false){return s}function w(){if(s.options.position.type!=="static"){s.focus()}s.onShow.call(s,y);if(f.browser.msie){s.elements.tooltip.get(0).style.removeAttribute("filter")}}s.cache.toggle=1;if(s.options.position.type!=="static"){s.updatePosition(y,(s.options.show.effect.length>0))}if(typeof s.options.show.solo=="object"){z=f(s.options.show.solo)}else{if(s.options.show.solo===true){z=f("div.qtip").not(s.elements.tooltip)}}if(z){z.each(function(){if(f(this).qtip("api").status.rendered===true){f(this).qtip("api").hide()}})}if(typeof s.options.show.effect.type=="function"){s.options.show.effect.type.call(s.elements.tooltip,s.options.show.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.show.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeIn(s.options.show.effect.length,w);break;case"slide":s.elements.tooltip.slideDown(s.options.show.effect.length,function(){w();if(s.options.position.type!=="static"){s.updatePosition(y,true)}});break;case"grow":s.elements.tooltip.show(s.options.show.effect.length,w);break;default:s.elements.tooltip.show(null,w);break}s.elements.tooltip.addClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_SHOWN,"show")},hide:function(y){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"hide")}else{if(s.elements.tooltip.css("display")==="none"){return s}}clearTimeout(s.timers.show);s.elements.tooltip.stop(true,false);x=s.beforeHide.call(s,y);if(x===false){return s}function w(){s.onHide.call(s,y)}s.cache.toggle=0;if(typeof s.options.hide.effect.type=="function"){s.options.hide.effect.type.call(s.elements.tooltip,s.options.hide.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.hide.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeOut(s.options.hide.effect.length,w);break;case"slide":s.elements.tooltip.slideUp(s.options.hide.effect.length,w);break;case"grow":s.elements.tooltip.hide(s.options.hide.effect.length,w);break;default:s.elements.tooltip.hide(null,w);break}s.elements.tooltip.removeClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_HIDDEN,"hide")},updatePosition:function(w,x){var C,G,L,J,H,E,y,I,B,D,K,A,F,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updatePosition")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_POSITION_STATIC,"updatePosition")}}G={position:{left:0,top:0},dimensions:{height:0,width:0},corner:s.options.position.corner.target};L={position:s.getPosition(),dimensions:s.getDimensions(),corner:s.options.position.corner.tooltip};if(s.options.position.target!=="mouse"){if(s.options.position.target.get(0).nodeName.toLowerCase()=="area"){J=s.options.position.target.attr("coords").split(",");for(C=0;C<J.length;C++){J[C]=parseInt(J[C])}H=s.options.position.target.parent("map").attr("name");E=f('img[usemap="#'+H+'"]:first').offset();G.position={left:Math.floor(E.left+J[0]),top:Math.floor(E.top+J[1])};switch(s.options.position.target.attr("shape").toLowerCase()){case"rect":G.dimensions={width:Math.ceil(Math.abs(J[2]-J[0])),height:Math.ceil(Math.abs(J[3]-J[1]))};break;case"circle":G.dimensions={width:J[2]+1,height:J[2]+1};break;case"poly":G.dimensions={width:J[0],height:J[1]};for(C=0;C<J.length;C++){if(C%2==0){if(J[C]>G.dimensions.width){G.dimensions.width=J[C]}if(J[C]<J[0]){G.position.left=Math.floor(E.left+J[C])}}else{if(J[C]>G.dimensions.height){G.dimensions.height=J[C]}if(J[C]<J[1]){G.position.top=Math.floor(E.top+J[C])}}}G.dimensions.width=G.dimensions.width-(G.position.left-E.left);G.dimensions.height=G.dimensions.height-(G.position.top-E.top);break;default:return f.fn.qtip.log.error.call(s,4,f.fn.qtip.constants.INVALID_AREA_SHAPE,"updatePosition");break}G.dimensions.width-=2;G.dimensions.height-=2}else{if(s.options.position.target.add(document.body).length===1){G.position={left:f(document).scrollLeft(),top:f(document).scrollTop()};G.dimensions={height:f(window).height(),width:f(window).width()}}else{if(typeof s.options.position.target.attr("qtip")!=="undefined"){G.position=s.options.position.target.qtip("api").cache.position}else{G.position=s.options.position.target.offset()}G.dimensions={height:s.options.position.target.outerHeight(),width:s.options.position.target.outerWidth()}}}y=f.extend({},G.position);if(G.corner.search(/right/i)!==-1){y.left+=G.dimensions.width}if(G.corner.search(/bottom/i)!==-1){y.top+=G.dimensions.height}if(G.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left+=(G.dimensions.width/2)}if(G.corner.search(/((left|right)Middle)|center/)!==-1){y.top+=(G.dimensions.height/2)}}else{G.position=y={left:s.cache.mouse.x,top:s.cache.mouse.y};G.dimensions={height:1,width:1}}if(L.corner.search(/right/i)!==-1){y.left-=L.dimensions.width}if(L.corner.search(/bottom/i)!==-1){y.top-=L.dimensions.height}if(L.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left-=(L.dimensions.width/2)}if(L.corner.search(/((left|right)Middle)|center/)!==-1){y.top-=(L.dimensions.height/2)}I=(f.browser.msie)?1:0;B=(f.browser.msie&&parseInt(f.browser.version.charAt(0))===6)?1:0;if(s.options.style.border.radius>0){if(L.corner.search(/Left/)!==-1){y.left-=s.options.style.border.radius}else{if(L.corner.search(/Right/)!==-1){y.left+=s.options.style.border.radius}}if(L.corner.search(/Top/)!==-1){y.top-=s.options.style.border.radius}else{if(L.corner.search(/Bottom/)!==-1){y.top+=s.options.style.border.radius}}}if(I){if(L.corner.search(/top/)!==-1){y.top-=I}else{if(L.corner.search(/bottom/)!==-1){y.top+=I}}if(L.corner.search(/left/)!==-1){y.left-=I}else{if(L.corner.search(/right/)!==-1){y.left+=I}}if(L.corner.search(/leftMiddle|rightMiddle/)!==-1){y.top-=1}}if(s.options.position.adjust.screen===true){y=o.call(s,y,G,L)}if(s.options.position.target==="mouse"&&s.options.position.adjust.mouse===true){if(s.options.position.adjust.screen===true&&s.elements.tip){K=s.elements.tip.attr("rel")}else{K=s.options.position.corner.tooltip}y.left+=(K.search(/right/i)!==-1)?-6:6;y.top+=(K.search(/bottom/i)!==-1)?-6:6}if(!s.elements.bgiframe&&f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){f("select, object").each(function(){A=f(this).offset();A.bottom=A.top+f(this).height();A.right=A.left+f(this).width();if(y.top+L.dimensions.height>=A.top&&y.left+L.dimensions.width>=A.left){k.call(s)}})}y.left+=s.options.position.adjust.x;y.top+=s.options.position.adjust.y;F=s.getPosition();if(y.left!=F.left||y.top!=F.top){z=s.beforePositionUpdate.call(s,w);if(z===false){return s}s.cache.position=y;if(x===true){s.status.animated=true;s.elements.tooltip.animate(y,200,"swing",function(){s.status.animated=false})}else{s.elements.tooltip.css(y)}s.onPositionUpdate.call(s,w);if(typeof w!=="undefined"&&w.type&&w.type!=="mousemove"){f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_POSITION_UPDATED,"updatePosition")}}return s},updateWidth:function(w){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateWidth")}else{if(w&&typeof w!=="number"){return f.fn.qtip.log.error.call(s,2,"newWidth must be of type number","updateWidth")}}x=s.elements.contentWrapper.siblings().add(s.elements.tip).add(s.elements.button);if(!w){if(typeof s.options.style.width.value=="number"){w=s.options.style.width.value}else{s.elements.tooltip.css({width:"auto"});x.hide();if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"normal"})}w=s.getDimensions().width+1;if(!s.options.style.width.value){if(w>s.options.style.width.max){w=s.options.style.width.max}if(w<s.options.style.width.min){w=s.options.style.width.min}}}}if(w%2!==0){w-=1}s.elements.tooltip.width(w);x.show();if(s.options.style.border.radius){s.elements.tooltip.find(".qtip-betweenCorners").each(function(y){f(this).width(w-(s.options.style.border.radius*2))})}if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"1"});s.elements.wrapper.width(w);if(s.elements.bgiframe){s.elements.bgiframe.width(w).height(s.getDimensions.height)}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_WIDTH_UPDATED,"updateWidth")},updateStyle:function(w){var z,A,x,y,B;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateStyle")}else{if(typeof w!=="string"||!f.fn.qtip.styles[w]){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.STYLE_NOT_DEFINED,"updateStyle")}}s.options.style=a.call(s,f.fn.qtip.styles[w],s.options.user.style);s.elements.content.css(q(s.options.style));if(s.options.content.title.text!==false){s.elements.title.css(q(s.options.style.title,true))}s.elements.contentWrapper.css({borderColor:s.options.style.border.color});if(s.options.style.tip.corner!==false){if(f("<canvas>").get(0).getContext){z=s.elements.tooltip.find(".qtip-tip canvas:first");x=z.get(0).getContext("2d");x.clearRect(0,0,300,300);y=z.parent("div[rel]:first").attr("rel");B=b(y,s.options.style.tip.size.width,s.options.style.tip.size.height);h.call(s,z,B,s.options.style.tip.color||s.options.style.border.color)}else{if(f.browser.msie){z=s.elements.tooltip.find('.qtip-tip [nodeName="shape"]');z.attr("fillcolor",s.options.style.tip.color||s.options.style.border.color)}}}if(s.options.style.border.radius>0){s.elements.tooltip.find(".qtip-betweenCorners").css({backgroundColor:s.options.style.border.color});if(f("<canvas>").get(0).getContext){A=g(s.options.style.border.radius);s.elements.tooltip.find(".qtip-wrapper canvas").each(function(){x=f(this).get(0).getContext("2d");x.clearRect(0,0,300,300);y=f(this).parent("div[rel]:first").attr("rel");r.call(s,f(this),A[y],s.options.style.border.radius,s.options.style.border.color)})}else{if(f.browser.msie){s.elements.tooltip.find('.qtip-wrapper [nodeName="arc"]').each(function(){f(this).attr("fillcolor",s.options.style.border.color)})}}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_STYLE_UPDATED,"updateStyle")},updateContent:function(A,y){var z,x,w;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateContent")}else{if(!A){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateContent")}}z=s.beforeContentUpdate.call(s,A);if(typeof z=="string"){A=z}else{if(z===false){return}}if(f.browser.msie){s.elements.contentWrapper.children().css({zoom:"normal"})}if(A.jquery&&A.length>0){A.clone(true).appendTo(s.elements.content).show()}else{s.elements.content.html(A)}x=s.elements.content.find("img[complete=false]");if(x.length>0){w=0;x.each(function(C){f('<img src="'+f(this).attr("src")+'" />').load(function(){if(++w==x.length){B()}})})}else{B()}function B(){s.updateWidth();if(y!==false){if(s.options.position.type!=="static"){s.updatePosition(s.elements.tooltip.is(":visible"),true)}if(s.options.style.tip.corner!==false){n.call(s)}}}s.onContentUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_UPDATED,"loadContent")},loadContent:function(w,z,A){var y;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"loadContent")}y=s.beforeContentLoad.call(s);if(y===false){return s}if(A=="post"){f.post(w,z,x)}else{f.get(w,z,x)}function x(B){s.onContentLoad.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_LOADED,"loadContent");s.updateContent(B)}return s},updateTitle:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateTitle")}else{if(!w){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateTitle")}}returned=s.beforeTitleUpdate.call(s);if(returned===false){return s}if(s.elements.button){s.elements.button=s.elements.button.clone(true)}s.elements.title.html(w);if(s.elements.button){s.elements.title.prepend(s.elements.button)}s.onTitleUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_TITLE_UPDATED,"updateTitle")},focus:function(A){var y,x,w,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"focus")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_FOCUS_STATIC,"focus")}}y=parseInt(s.elements.tooltip.css("z-index"));x=6000+f("div.qtip[qtip]").length-1;if(!s.status.focused&&y!==x){z=s.beforeFocus.call(s,A);if(z===false){return s}f("div.qtip[qtip]").not(s.elements.tooltip).each(function(){if(f(this).qtip("api").status.rendered===true){w=parseInt(f(this).css("z-index"));if(typeof w=="number"&&w>-1){f(this).css({zIndex:parseInt(f(this).css("z-index"))-1})}f(this).qtip("api").status.focused=false}});s.elements.tooltip.css({zIndex:x});s.status.focused=true;s.onFocus.call(s,A);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_FOCUSED,"focus")}return s},disable:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"disable")}if(w){if(!s.status.disabled){s.status.disabled=true;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DISABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_DISABLED,"disable")}}else{if(s.status.disabled){s.status.disabled=false;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_ENABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_ENABLED,"disable")}}return s},destroy:function(){var w,x,y;x=s.beforeDestroy.call(s);if(x===false){return s}if(s.status.rendered){s.options.show.when.target.unbind("mousemove.qtip",s.updatePosition);s.options.show.when.target.unbind("mouseout.qtip",s.hide);s.options.show.when.target.unbind(s.options.show.when.event+".qtip");s.options.hide.when.target.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind("mouseover.qtip",s.focus);s.elements.tooltip.remove()}else{s.options.show.when.target.unbind(s.options.show.when.event+".qtip-create")}if(typeof s.elements.target.data("qtip")=="object"){y=s.elements.target.data("qtip").interfaces;if(typeof y=="object"&&y.length>0){for(w=0;w<y.length-1;w++){if(y[w].id==s.id){y.splice(w,1)}}}}delete f.fn.qtip.interfaces[s.id];if(typeof y=="object"&&y.length>0){s.elements.target.data("qtip").current=y.length-1}else{s.elements.target.removeData("qtip")}s.onDestroy.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DESTROYED,"destroy");return s.elements.target},getPosition:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getPosition")}w=(s.elements.tooltip.css("display")!=="none")?false:true;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x=s.elements.tooltip.offset();if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x},getDimensions:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getDimensions")}w=(!s.elements.tooltip.is(":visible"))?true:false;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x={height:s.elements.tooltip.outerHeight(),width:s.elements.tooltip.outerWidth()};if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x}})}function p(){var s,w,u,t,v,y,x;s=this;s.beforeRender.call(s);s.status.rendered=true;s.elements.tooltip='<div qtip="'+s.id+'" class="qtip '+(s.options.style.classes.tooltip||s.options.style)+'"style="display:none; -moz-border-radius:0; -webkit-border-radius:0; border-radius:0;position:'+s.options.position.type+';"> <div class="qtip-wrapper" style="position:relative; overflow:hidden; text-align:left;"> <div class="qtip-contentWrapper" style="overflow:hidden;"> <div class="qtip-content '+s.options.style.classes.content+'"></div></div></div></div>';s.elements.tooltip=f(s.elements.tooltip);s.elements.tooltip.appendTo(s.options.position.container);s.elements.tooltip.data("qtip",{current:0,interfaces:[s]});s.elements.wrapper=s.elements.tooltip.children("div:first");s.elements.contentWrapper=s.elements.wrapper.children("div:first").css({background:s.options.style.background});s.elements.content=s.elements.contentWrapper.children("div:first").css(q(s.options.style));if(f.browser.msie){s.elements.wrapper.add(s.elements.content).css({zoom:1})}if(s.options.hide.when.event=="unfocus"){s.elements.tooltip.attr("unfocus",true)}if(typeof s.options.style.width.value=="number"){s.updateWidth()}if(f("<canvas>").get(0).getContext||f.browser.msie){if(s.options.style.border.radius>0){m.call(s)}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color})}if(s.options.style.tip.corner!==false){e.call(s)}}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color});s.options.style.border.radius=0;s.options.style.tip.corner=false;f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.CANVAS_VML_NOT_SUPPORTED,"render")}if((typeof s.options.content.text=="string"&&s.options.content.text.length>0)||(s.options.content.text.jquery&&s.options.content.text.length>0)){u=s.options.content.text}else{if(typeof s.elements.target.attr("title")=="string"&&s.elements.target.attr("title").length>0){u=s.elements.target.attr("title").replace("\\n","<br />");s.elements.target.attr("title","")}else{if(typeof s.elements.target.attr("alt")=="string"&&s.elements.target.attr("alt").length>0){u=s.elements.target.attr("alt").replace("\\n","<br />");s.elements.target.attr("alt","")}else{u=" ";f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.NO_VALID_CONTENT,"render")}}}if(s.options.content.title.text!==false){j.call(s)}s.updateContent(u);l.call(s);if(s.options.show.ready===true){s.show()}if(s.options.content.url!==false){t=s.options.content.url;v=s.options.content.data;y=s.options.content.method||"get";s.loadContent(t,v,y)}s.onRender.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_RENDERED,"render")}function m(){var F,z,t,B,x,E,u,G,D,y,w,C,A,s,v;F=this;F.elements.wrapper.find(".qtip-borderBottom, .qtip-borderTop").remove();t=F.options.style.border.width;B=F.options.style.border.radius;x=F.options.style.border.color||F.options.style.tip.color;E=g(B);u={};for(z in E){u[z]='<div rel="'+z+'" style="'+((z.search(/Left/)!==-1)?"left":"right")+":0; position:absolute; height:"+B+"px; width:"+B+'px; overflow:hidden; line-height:0.1px; font-size:1px">';if(f("<canvas>").get(0).getContext){u[z]+='<canvas height="'+B+'" width="'+B+'" style="vertical-align: top"></canvas>'}else{if(f.browser.msie){G=B*2+3;u[z]+='<v:arc stroked="false" fillcolor="'+x+'" startangle="'+E[z][0]+'" endangle="'+E[z][1]+'" style="width:'+G+"px; height:"+G+"px; margin-top:"+((z.search(/bottom/)!==-1)?-2:-1)+"px; margin-left:"+((z.search(/Right/)!==-1)?E[z][2]-3.5:-1)+'px; vertical-align:top; display:inline-block; behavior:url(#default#VML)"></v:arc>'}}u[z]+="</div>"}D=F.getDimensions().width-(Math.max(t,B)*2);y='<div class="qtip-betweenCorners" style="height:'+B+"px; width:"+D+"px; overflow:hidden; background-color:"+x+'; line-height:0.1px; font-size:1px;">';w='<div class="qtip-borderTop" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.topLeft+u.topRight+y;F.elements.wrapper.prepend(w);C='<div class="qtip-borderBottom" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.bottomLeft+u.bottomRight+y;F.elements.wrapper.append(C);if(f("<canvas>").get(0).getContext){F.elements.wrapper.find("canvas").each(function(){A=E[f(this).parent("[rel]:first").attr("rel")];r.call(F,f(this),A,B,x)})}else{if(f.browser.msie){F.elements.tooltip.append('<v:image style="behavior:url(#default#VML);"></v:image>')}}s=Math.max(B,(B+(t-B)));v=Math.max(t-B,0);F.elements.contentWrapper.css({border:"0px solid "+x,borderWidth:v+"px "+s+"px"})}function r(u,w,s,t){var v=u.get(0).getContext("2d");v.fillStyle=t;v.beginPath();v.arc(w[0],w[1],s,0,Math.PI*2,false);v.fill()}function e(v){var t,s,x,u,w;t=this;if(t.elements.tip!==null){t.elements.tip.remove()}s=t.options.style.tip.color||t.options.style.border.color;if(t.options.style.tip.corner===false){return}else{if(!v){v=t.options.style.tip.corner}}x=b(v,t.options.style.tip.size.width,t.options.style.tip.size.height);t.elements.tip='<div class="'+t.options.style.classes.tip+'" dir="ltr" rel="'+v+'" style="position:absolute; height:'+t.options.style.tip.size.height+"px; width:"+t.options.style.tip.size.width+'px; margin:0 auto; line-height:0.1px; font-size:1px;">';if(f("<canvas>").get(0).getContext){t.elements.tip+='<canvas height="'+t.options.style.tip.size.height+'" width="'+t.options.style.tip.size.width+'"></canvas>'}else{if(f.browser.msie){u=t.options.style.tip.size.width+","+t.options.style.tip.size.height;w="m"+x[0][0]+","+x[0][1];w+=" l"+x[1][0]+","+x[1][1];w+=" "+x[2][0]+","+x[2][1];w+=" xe";t.elements.tip+='<v:shape fillcolor="'+s+'" stroked="false" filled="true" path="'+w+'" coordsize="'+u+'" style="width:'+t.options.style.tip.size.width+"px; height:"+t.options.style.tip.size.height+"px; line-height:0.1px; display:inline-block; behavior:url(#default#VML); vertical-align:"+((v.search(/top/)!==-1)?"bottom":"top")+'"></v:shape>';t.elements.tip+='<v:image style="behavior:url(#default#VML);"></v:image>';t.elements.contentWrapper.css("position","relative")}}t.elements.tooltip.prepend(t.elements.tip+"</div>");t.elements.tip=t.elements.tooltip.find("."+t.options.style.classes.tip).eq(0);if(f("<canvas>").get(0).getContext){h.call(t,t.elements.tip.find("canvas:first"),x,s)}if(v.search(/top/)!==-1&&f.browser.msie&&parseInt(f.browser.version.charAt(0))===6){t.elements.tip.css({marginTop:-4})}n.call(t,v)}function h(t,v,s){var u=t.get(0).getContext("2d");u.fillStyle=s;u.beginPath();u.moveTo(v[0][0],v[0][1]);u.lineTo(v[1][0],v[1][1]);u.lineTo(v[2][0],v[2][1]);u.fill()}function n(u){var t,w,s,x,v;t=this;if(t.options.style.tip.corner===false||!t.elements.tip){return}if(!u){u=t.elements.tip.attr("rel")}w=positionAdjust=(f.browser.msie)?1:0;t.elements.tip.css(u.match(/left|right|top|bottom/)[0],0);if(u.search(/top|bottom/)!==-1){if(f.browser.msie){if(parseInt(f.browser.version.charAt(0))===6){positionAdjust=(u.search(/top/)!==-1)?-3:1}else{positionAdjust=(u.search(/top/)!==-1)?1:2}}if(u.search(/Middle/)!==-1){t.elements.tip.css({left:"50%",marginLeft:-(t.options.style.tip.size.width/2)})}else{if(u.search(/Left/)!==-1){t.elements.tip.css({left:t.options.style.border.radius-w})}else{if(u.search(/Right/)!==-1){t.elements.tip.css({right:t.options.style.border.radius+w})}}}if(u.search(/top/)!==-1){t.elements.tip.css({top:-positionAdjust})}else{t.elements.tip.css({bottom:positionAdjust})}}else{if(u.search(/left|right/)!==-1){if(f.browser.msie){positionAdjust=(parseInt(f.browser.version.charAt(0))===6)?1:((u.search(/left/)!==-1)?1:2)}if(u.search(/Middle/)!==-1){t.elements.tip.css({top:"50%",marginTop:-(t.options.style.tip.size.height/2)})}else{if(u.search(/Top/)!==-1){t.elements.tip.css({top:t.options.style.border.radius-w})}else{if(u.search(/Bottom/)!==-1){t.elements.tip.css({bottom:t.options.style.border.radius+w})}}}if(u.search(/left/)!==-1){t.elements.tip.css({left:-positionAdjust})}else{t.elements.tip.css({right:positionAdjust})}}}s="padding-"+u.match(/left|right|top|bottom/)[0];x=t.options.style.tip.size[(s.search(/left|right/)!==-1)?"width":"height"];t.elements.tooltip.css("padding",0);t.elements.tooltip.css(s,x);if(f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){v=parseInt(t.elements.tip.css("margin-top"))||0;v+=parseInt(t.elements.content.css("margin-top"))||0;t.elements.tip.css({marginTop:v})}}function j(){var s=this;if(s.elements.title!==null){s.elements.title.remove()}s.elements.title=f('<div class="'+s.options.style.classes.title+'">').css(q(s.options.style.title,true)).css({zoom:(f.browser.msie)?1:0}).prependTo(s.elements.contentWrapper);if(s.options.content.title.text){s.updateTitle.call(s,s.options.content.title.text)}if(s.options.content.title.button!==false&&typeof s.options.content.title.button=="string"){s.elements.button=f('<a class="'+s.options.style.classes.button+'" style="float:right; position: relative"></a>').css(q(s.options.style.button,true)).html(s.options.content.title.button).prependTo(s.elements.title).click(function(t){if(!s.status.disabled){s.hide(t)}})}}function l(){var t,v,u,s;t=this;v=t.options.show.when.target;u=t.options.hide.when.target;if(t.options.hide.fixed){u=u.add(t.elements.tooltip)}if(t.options.hide.when.event=="inactive"){s=["click","dblclick","mousedown","mouseup","mousemove","mouseout","mouseenter","mouseleave","mouseover"];function y(z){if(t.status.disabled===true){return}clearTimeout(t.timers.inactive);t.timers.inactive=setTimeout(function(){f(s).each(function(){u.unbind(this+".qtip-inactive");t.elements.content.unbind(this+".qtip-inactive")});t.hide(z)},t.options.hide.delay)}}else{if(t.options.hide.fixed===true){t.elements.tooltip.bind("mouseover.qtip",function(){if(t.status.disabled===true){return}clearTimeout(t.timers.hide)})}}function x(z){if(t.status.disabled===true){return}if(t.options.hide.when.event=="inactive"){f(s).each(function(){u.bind(this+".qtip-inactive",y);t.elements.content.bind(this+".qtip-inactive",y)});y()}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.timers.show=setTimeout(function(){t.show(z)},t.options.show.delay)}function w(z){if(t.status.disabled===true){return}if(t.options.hide.fixed===true&&t.options.hide.when.event.search(/mouse(out|leave)/i)!==-1&&f(z.relatedTarget).parents("div.qtip[qtip]").length>0){z.stopPropagation();z.preventDefault();clearTimeout(t.timers.hide);return false}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.elements.tooltip.stop(true,true);t.timers.hide=setTimeout(function(){t.hide(z)},t.options.hide.delay)}if((t.options.show.when.target.add(t.options.hide.when.target).length===1&&t.options.show.when.event==t.options.hide.when.event&&t.options.hide.when.event!=="inactive")||t.options.hide.when.event=="unfocus"){t.cache.toggle=0;v.bind(t.options.show.when.event+".qtip",function(z){if(t.cache.toggle==0){x(z)}else{w(z)}})}else{v.bind(t.options.show.when.event+".qtip",x);if(t.options.hide.when.event!=="inactive"){u.bind(t.options.hide.when.event+".qtip",w)}}if(t.options.position.type.search(/(fixed|absolute)/)!==-1){t.elements.tooltip.bind("mouseover.qtip",t.focus)}if(t.options.position.target==="mouse"&&t.options.position.type!=="static"){v.bind("mousemove.qtip",function(z){t.cache.mouse={x:z.pageX,y:z.pageY};if(t.status.disabled===false&&t.options.position.adjust.mouse===true&&t.options.position.type!=="static"&&t.elements.tooltip.css("display")!=="none"){t.updatePosition(z)}})}}function o(u,v,A){var z,s,x,y,t,w;z=this;if(A.corner=="center"){return v.position}s=f.extend({},u);y={x:false,y:false};t={left:(s.left<f.fn.qtip.cache.screen.scroll.left),right:(s.left+A.dimensions.width+2>=f.fn.qtip.cache.screen.width+f.fn.qtip.cache.screen.scroll.left),top:(s.top<f.fn.qtip.cache.screen.scroll.top),bottom:(s.top+A.dimensions.height+2>=f.fn.qtip.cache.screen.height+f.fn.qtip.cache.screen.scroll.top)};x={left:(t.left&&(A.corner.search(/right/i)!=-1||(A.corner.search(/right/i)==-1&&!t.right))),right:(t.right&&(A.corner.search(/left/i)!=-1||(A.corner.search(/left/i)==-1&&!t.left))),top:(t.top&&A.corner.search(/top/i)==-1),bottom:(t.bottom&&A.corner.search(/bottom/i)==-1)};if(x.left){if(z.options.position.target!=="mouse"){s.left=v.position.left+v.dimensions.width}else{s.left=z.cache.mouse.x}y.x="Left"}else{if(x.right){if(z.options.position.target!=="mouse"){s.left=v.position.left-A.dimensions.width}else{s.left=z.cache.mouse.x-A.dimensions.width}y.x="Right"}}if(x.top){if(z.options.position.target!=="mouse"){s.top=v.position.top+v.dimensions.height}else{s.top=z.cache.mouse.y}y.y="top"}else{if(x.bottom){if(z.options.position.target!=="mouse"){s.top=v.position.top-A.dimensions.height}else{s.top=z.cache.mouse.y-A.dimensions.height}y.y="bottom"}}if(s.left<0){s.left=u.left;y.x=false}if(s.top<0){s.top=u.top;y.y=false}if(z.options.style.tip.corner!==false){s.corner=new String(A.corner);if(y.x!==false){s.corner=s.corner.replace(/Left|Right|Middle/,y.x)}if(y.y!==false){s.corner=s.corner.replace(/top|bottom/,y.y)}if(s.corner!==z.elements.tip.attr("rel")){e.call(z,s.corner)}}return s}function q(u,t){var v,s;v=f.extend(true,{},u);for(s in v){if(t===true&&s.search(/(tip|classes)/i)!==-1){delete v[s]}else{if(!t&&s.search(/(width|border|tip|title|classes|user)/i)!==-1){delete v[s]}}}return v}function c(s){if(typeof s.tip!=="object"){s.tip={corner:s.tip}}if(typeof s.tip.size!=="object"){s.tip.size={width:s.tip.size,height:s.tip.size}}if(typeof s.border!=="object"){s.border={width:s.border}}if(typeof s.width!=="object"){s.width={value:s.width}}if(typeof s.width.max=="string"){s.width.max=parseInt(s.width.max.replace(/([0-9]+)/i,"$1"))}if(typeof s.width.min=="string"){s.width.min=parseInt(s.width.min.replace(/([0-9]+)/i,"$1"))}if(typeof s.tip.size.x=="number"){s.tip.size.width=s.tip.size.x;delete s.tip.size.x}if(typeof s.tip.size.y=="number"){s.tip.size.height=s.tip.size.y;delete s.tip.size.y}return s}function a(){var s,t,u,x,v,w;s=this;u=[true,{}];for(t=0;t<arguments.length;t++){u.push(arguments[t])}x=[f.extend.apply(f,u)];while(typeof x[0].name=="string"){x.unshift(c(f.fn.qtip.styles[x[0].name]))}x.unshift(true,{classes:{tooltip:"qtip-"+(arguments[0].name||"defaults")}},f.fn.qtip.styles.defaults);v=f.extend.apply(f,x);w=(f.browser.msie)?1:0;v.tip.size.width+=w;v.tip.size.height+=w;if(v.tip.size.width%2>0){v.tip.size.width+=1}if(v.tip.size.height%2>0){v.tip.size.height+=1}if(v.tip.corner===true){v.tip.corner=(s.options.position.corner.tooltip==="center")?false:s.options.position.corner.tooltip}return v}function b(v,u,t){var s={bottomRight:[[0,0],[u,t],[u,0]],bottomLeft:[[0,0],[u,0],[0,t]],topRight:[[0,t],[u,0],[u,t]],topLeft:[[0,0],[0,t],[u,t]],topMiddle:[[0,t],[u/2,0],[u,t]],bottomMiddle:[[0,0],[u,0],[u/2,t]],rightMiddle:[[0,0],[u,t/2],[0,t]],leftMiddle:[[u,0],[u,t],[0,t/2]]};s.leftTop=s.bottomRight;s.rightTop=s.bottomLeft;s.leftBottom=s.topRight;s.rightBottom=s.topLeft;return s[v]}function g(s){var t;if(f("<canvas>").get(0).getContext){t={topLeft:[s,s],topRight:[0,s],bottomLeft:[s,0],bottomRight:[0,0]}}else{if(f.browser.msie){t={topLeft:[-90,90,0],topRight:[-90,90,-s],bottomLeft:[90,270,0],bottomRight:[90,270,-s]}}}return t}function k(){var s,t,u;s=this;u=s.getDimensions();t='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:false" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=\'0\'); border: 1px solid red; height:'+u.height+"px; width:"+u.width+'px" />';s.elements.bgiframe=s.elements.wrapper.prepend(t).children(".qtip-bgiframe:first")}f(document).ready(function(){f.fn.qtip.cache={screen:{scroll:{left:f(window).scrollLeft(),top:f(window).scrollTop()},width:f(window).width(),height:f(window).height()}};var s;f(window).bind("resize scroll",function(t){clearTimeout(s);s=setTimeout(function(){if(t.type==="scroll"){f.fn.qtip.cache.screen.scroll={left:f(window).scrollLeft(),top:f(window).scrollTop()}}else{f.fn.qtip.cache.screen.width=f(window).width();f.fn.qtip.cache.screen.height=f(window).height()}for(i=0;i<f.fn.qtip.interfaces.length;i++){var u=f.fn.qtip.interfaces[i];if(u.status.rendered===true&&(u.options.position.type!=="static"||u.options.position.adjust.scroll&&t.type==="scroll"||u.options.position.adjust.resize&&t.type==="resize")){u.updatePosition(t,true)}}},100)});f(document).bind("mousedown.qtip",function(t){if(f(t.target).parents("div.qtip").length===0){f(".qtip[unfocus]").each(function(){var u=f(this).qtip("api");if(f(this).is(":visible")&&!u.status.disabled&&f(t.target).add(u.elements.target).length>1){u.hide(t)}})}})});f.fn.qtip.interfaces=[];f.fn.qtip.log={error:function(){return this}};f.fn.qtip.constants={};f.fn.qtip.defaults={content:{prerender:false,text:false,url:false,data:null,title:{text:false,button:false}},position:{target:false,corner:{target:"bottomRight",tooltip:"topLeft"},adjust:{x:0,y:0,mouse:true,screen:false,scroll:true,resize:true},type:"absolute",container:false},show:{when:{target:false,event:"mouseover"},effect:{type:"fade",length:100},delay:140,solo:false,ready:false},hide:{when:{target:false,event:"mouseout"},effect:{type:"fade",length:100},delay:0,fixed:false},api:{beforeRender:function(){},onRender:function(){},beforePositionUpdate:function(){},onPositionUpdate:function(){},beforeShow:function(){},onShow:function(){},beforeHide:function(){},onHide:function(){},beforeContentUpdate:function(){},onContentUpdate:function(){},beforeContentLoad:function(){},onContentLoad:function(){},beforeTitleUpdate:function(){},onTitleUpdate:function(){},beforeDestroy:function(){},onDestroy:function(){},beforeFocus:function(){},onFocus:function(){}}};f.fn.qtip.styles={defaults:{background:"white",color:"#111",overflow:"hidden",textAlign:"left",width:{min:0,max:250},padding:"5px 9px",border:{width:1,radius:0,color:"#d3d3d3"},tip:{corner:false,color:false,size:{width:13,height:13},opacity:1},title:{background:"#e1e1e1",fontWeight:"bold",padding:"7px 12px"},button:{cursor:"pointer"},classes:{target:"",tip:"qtip-tip",title:"qtip-title",button:"qtip-button",content:"qtip-content",active:"qtip-active"}},cream:{border:{width:3,radius:0,color:"#F9E98E"},title:{background:"#F0DE7D",color:"#A27D35"},background:"#FBF7AA",color:"#A27D35",classes:{tooltip:"qtip-cream"}},light:{border:{width:3,radius:0,color:"#E2E2E2"},title:{background:"#f1f1f1",color:"#454545"},background:"white",color:"#454545",classes:{tooltip:"qtip-light"}},dark:{border:{width:3,radius:0,color:"#303030"},title:{background:"#404040",color:"#f3f3f3"},background:"#505050",color:"#f3f3f3",classes:{tooltip:"qtip-dark"}},red:{border:{width:3,radius:0,color:"#CE6F6F"},title:{background:"#f28279",color:"#9C2F2F"},background:"#F79992",color:"#9C2F2F",classes:{tooltip:"qtip-red"}},green:{border:{width:3,radius:0,color:"#A9DB66"},title:{background:"#b9db8c",color:"#58792E"},background:"#CDE6AC",color:"#58792E",classes:{tooltip:"qtip-green"}},blue:{border:{width:3,radius:0,color:"#ADD9ED"},title:{background:"#D0E9F5",color:"#5E99BD"},background:"#E5F6FE",color:"#4D9FBF",classes:{tooltip:"qtip-blue"}}}})(jQuery);
16
-
17
-
18
-
19
-
20
-
21
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/dependencies/rickshaw/d3.v3.min.js DELETED
@@ -1,5 +0,0 @@
1
- !function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===la||n[0]===sa?sa+n:n}function l(n){return(n+="")[0]===sa?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=fa.length;r>e;++e){var u=fa[e]+t;if(u in n)return u}}function y(){}function x(){}function M(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new a;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function _(){Bo.event.preventDefault()}function b(){for(var n,t=Bo.event;n=t.sourceEvent;)t=n;return t}function w(n){for(var t=new x,e=0,r=arguments.length;++e<r;)t[arguments[e]]=M(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Bo.event;u.target=n,Bo.event=u,t[u.type].apply(e,r)}finally{Bo.event=i}}},t}function S(n){return ga(n,ya),n}function k(n){return"function"==typeof n?n:function(){return pa(n,this)}}function E(n){return"function"==typeof n?n:function(){return va(n,this)}}function A(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Bo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function C(n){return n.trim().replace(/\s+/g," ")}function N(n){return new RegExp("(?:^|\\s+)"+Bo.requote(n)+"(?:\\s+|$)","g")}function z(n){return(n+"").trim().split(/^|\s+/)}function L(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=z(n).map(T);var u=n.length;return"function"==typeof t?r:e}function T(n){var t=N(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",C(u+" "+n))):e.setAttribute("class",C(u.replace(t," ")))}}function q(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function R(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function D(n){return"function"==typeof n?n:(n=Bo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function P(n){return{__data__:n}}function U(n){return function(){return ma(this,n)}}function j(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function F(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function H(n){return ga(n,Ma),n}function O(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function Y(){var n=this.__transition__;n&&++n.active}function I(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Jo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Bo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=Z;a>0&&(n=n.slice(0,a));var l=ba.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=Bo.event;Bo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Bo.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++Sa,t="click"+n,e=Bo.select(Qo).on("touchmove"+n,_).on("dragstart"+n,_).on("selectstart"+n,_);if(wa){var r=Ko.style,u=r[wa];r[wa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),wa&&(r[wa]=u),i&&(e.on(t,function(){_(),o()},!0),setTimeout(o,0))}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>ka&&(Qo.scrollX||Qo.scrollY)){e=Bo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();ka=!(u.f||u.e),e.remove()}return ka?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return Bo.event.changedTouches[0].identifier}function W(){return Bo.event.target}function J(){return Qo}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Ea:Math.acos(n)}function nt(n){return n>1?Ca:-1>n?-Ca:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):Mt(""+n,_t,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=bt((n=Bo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=La)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):bt((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ya,r=gt(r)*Ia,i=gt(i)*Za,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ta,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):Mt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function Mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=$a.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function bt(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ya),u=pt((.2126729*n+.7151522*t+.072175*e)/Ia),i=pt((.0193339*n+.119192*t+.9503041*e)/Za);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Ct(t,e,n,r)}}function Ct(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Bo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!Qo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Bo.event;Bo.event=n;try{o.progress.call(i,c)}finally{Bo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Jo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Bo.rebind(i,o,"on"),null==r?i:i.get(Nt(r))}function Nt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function Lt(){var n=Tt(),t=qt()-n;t>24?(isFinite(t)&&(clearTimeout(Ga),Ga=setTimeout(Lt,t)),Ja=0):(Ja=1,Qa(Lt))}function Tt(){var n=Date.now();for(Ka=Ba;Ka;)n>=Ka.t&&(Ka.f=Ka.c(n-Ka.t)),Ka=Ka.n;return n}function qt(){for(var n,t=Ba,e=1/0;t;)t.f?t=n?n.n=t.n:Ba=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Wa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ca(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=tc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=ec.get(g)||Ut;var x=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=Bo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var M,_,b=n.lastIndexOf(".");if(0>b){var w=y?n.lastIndexOf("e"):-1;0>w?(M=n,_=""):(M=n.substring(0,w),_=n.substring(w))}else M=n.substring(0,b),_=t+n.substring(b+1);!l&&f&&(M=i(M,1/0));var S=v.length+M.length+_.length+(x?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return x&&(M=i(k+M,k.length?s-_.length:1/0)),u+=v,n=M+_,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(x?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new uc(e-1)),1),e}function i(n,e){return t(n=new uc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{uc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{uc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{uc=jt;var r=new jt;return r._=t,n(r,e)._}finally{uc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=oc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&uc!==jt,o=new(i?jt:uc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(0|r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in oc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.slice(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function l(n,t,r){return e(n,C.X.toString(),t,r)}function s(n,t,e){var r=x.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{uc=jt;var t=new uc;return t._=n,r(t)}finally{uc=Date}}var r=t(n);return e.parse=function(n){try{uc=jt;var t=r.parse(n);return t&&t._}finally{uc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var x=Bo.map(),M=It(v),_=Zt(v),b=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+rc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(rc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(rc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(Bo.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|ca(t)/60,u=ca(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){cc.lastIndex=0;var r=cc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&hc.hasOwnProperty(n.type)&&hc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=La,t=t*La/2+Ea/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);pc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;vc.point=function(o,a){vc.point=n,r=(t=o)*La,u=Math.cos(a=(e=a)*La/2+Ea/4),i=Math.sin(a)},vc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function xe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function Me(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function _e(n,t){return ca(n[0]-t[0])<Na&&ca(n[1]-t[1])<Na}function be(n,t){n*=La;var e=Math.cos(t*=La);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++dc,yc+=(n-yc)/dc,xc+=(t-xc)/dc,Mc+=(e-Mc)/dc}function Se(){function n(n,u){n*=La;var i=Math.cos(u*=La),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);mc+=l,_c+=l*(t+(t=o)),bc+=l*(e+(e=a)),wc+=l*(r+(r=c)),we(t,e,r)}var t,e,r;Ac.point=function(u,i){u*=La;var o=Math.cos(i*=La);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),Ac.point=n,we(t,e,r)}}function ke(){Ac.point=be}function Ee(){function n(n,t){n*=La;var e=Math.cos(t*=La),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-Q(g)/h,v=Math.atan2(h,g);Sc+=p*l,kc+=p*s,Ec+=p*f,mc+=v,_c+=v*(r+(r=o)),bc+=v*(u+(u=a)),wc+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;Ac.point=function(o,a){t=o,e=a,Ac.point=n,o*=La;var c=Math.cos(a*=La);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},Ac.lineEnd=function(){n(t,e),Ac.lineEnd=ke,Ac.point=be}}function Ae(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(_e(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ze(e,n,null,!0),l=new ze(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new ze(r,n,null,!1),l=new ze(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),Ne(i),Ne(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Ne(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ze(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=Bo.merge(g);var n=je(m,p);g.length?(_||(i.polygonStart(),_=!0),Ce(g,Re,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=qe(),M=t(x),_=!1;return y}}function Te(n){return n.length>1}function qe(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Re(n,t){return((n=n.x)[0]<0?n[1]-Ca-Na:Ca-n[1])-((t=t.x)[0]<0?t[1]-Ca-Na:Ca-t[1])}function De(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Ea:-Ea,c=ca(i-e);ca(c-Ea)<Na?(n.point(e,r=(r+o)/2>0?Ca:-Ca),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Ea&&(ca(e-u)<Na&&(e-=u*Na),ca(i-a)<Na&&(i-=a*Na),r=Pe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Pe(n,t,e,r){var u,i,o=Math.sin(n-e);return ca(o)>Na?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Ue(n,t,e,r){var u;if(null==n)u=e*Ca,r.point(-Ea,u),r.point(0,u),r.point(Ea,u),r.point(Ea,0),r.point(Ea,-u),r.point(0,-u),r.point(-Ea,-u),r.point(-Ea,0),r.point(-Ea,u);else if(ca(n[0]-t[0])>Na){var i=n[0]<t[0]?Ea:-Ea;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function je(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;pc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Ea/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Ea/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Ea,k=p*x;if(pc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*Aa:_,S^h>=e^m>=e){var E=de(pe(f),pe(n));xe(E);var A=de(u,E);xe(A);var C=(S^_>=0?-1:1)*nt(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Na>i||Na>i&&0>pc)^1&o}function Fe(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Ea:-Ea),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(_e(e,g)||_e(p,g))&&(p[0]+=Na,p[1]+=Na,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&_e(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),x=m*m-y*(ve(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ye(d,(-m-M)/y);if(me(_,p),_=Me(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ca(A-Ea)<Na,N=C||Na>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ca(_[0]-w)<Na?k:E):k<=_[1]&&_[1]<=E:A>Ea^(w<=_[0]&&_[0]<=S)){var z=ye(d,(-m+M)/y);return me(z,p),[_,Me(z)]}}}function u(t,e){var r=o?n:Ea-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ca(i)>Na,c=gr(n,6*La);return Le(t,e,c,o?[0,-n]:[-Ea,n-Ea])}function He(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Oe(n,t,e,r){function u(r,u){return ca(r[0]-n)<Na?u>0?0:3:ca(r[0]-e)<Na?u>0?2:1:ca(r[1]-t)<Na?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Nc,Math.min(Nc,n)),t=Math.max(-Nc,Math.min(Nc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=qe(),C=He(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Bo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return N}}function Ye(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ie(n){var t=0,e=Ea/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Ea/180,e=n[1]*Ea/180):[180*(t/Ea),180*(e/Ea)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Lc+=u*n-r*t,r=n,u=t}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,t=r=i,e=u=o},Pc.lineEnd=function(){n(t,e)}}function Xe(n,t){Tc>n&&(Tc=n),n>Rc&&(Rc=n),qc>t&&(qc=t),t>Dc&&(Dc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){yc+=n,xc+=t,++Mc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);_c+=o*(t+n)/2,bc+=o*(e+r)/2,wc+=o,We(t=n,e=r)}var t,e;jc.point=function(r,u){jc.point=n,We(t=r,e=u)}}function Ge(){jc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);_c+=o*(r+n)/2,bc+=o*(u+t)/2,wc+=o,o=u*n-r*t,Sc+=o*(r+n),kc+=o*(u+t),Ec+=3*o,We(r=n,u=t)}var t,e,r,u;jc.point=function(i,o){jc.point=n,We(t=r=i,e=u=o)},jc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Aa)}function e(t,e){n.moveTo(t,e),a.point=r}functio