projects/genea/out/js/DataTables/DataTables-1.10.21/js/jquery.dataTables.js
1.
/*! DataTables 1.10.21
2.
 * ©2008-2020 SpryMedia Ltd - datatables.net/license
3.
 */
4.
 
5.
/**
6.
 * @summary     DataTables
7.
 * @description Paginate, search and order HTML tables
8.
 * @version     1.10.21
9.
 * @file        jquery.dataTables.js
10.
 * @author      SpryMedia Ltd
11.
 * @contact     www.datatables.net
12.
 * @copyright   Copyright 2008-2020 SpryMedia Ltd.
13.
 *
14.
 * This source file is free software, available under the following license:
15.
 *   MIT license - http://datatables.net/license
16.
 *
17.
 * This source file is distributed in the hope that it will be useful, but
18.
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19.
 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20.
 *
21.
 * For details please refer to: http://www.datatables.net
22.
 */
23.
 
24.
/*jslint evil: true, undef: true, browser: true */
25.
/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26.
 
27.
(function( factory ) {
28.
    "use strict";
29.
 
30.
    if ( typeof define === 'function' && define.amd ) {
31.
        // AMD
32.
        define( ['jquery'], function ( $ ) {
33.
            return factory( $, window, document );
34.
        } );
35.
    }
36.
    else if ( typeof exports === 'object' ) {
37.
        // CommonJS
38.
        module.exports = function (root, $) {
39.
            if ( ! root ) {
40.
                // CommonJS environments without a window global must pass a
41.
                // root. This will give an error otherwise
42.
                root = window;
43.
            }
44.
 
45.
            if ( ! $ ) {
46.
                $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
47.
                    require('jquery') :
48.
                    require('jquery')( root );
49.
            }
50.
 
51.
            return factory( $, root, root.document );
52.
        };
53.
    }
54.
    else {
55.
        // Browser
56.
        factory( jQuery, window, document );
57.
    }
58.
}
59.
(function( $, window, document, undefined ) {
60.
    "use strict";
61.
 
62.
    /**
63.
     * DataTables is a plug-in for the jQuery Javascript library. It is a highly
64.
     * flexible tool, based upon the foundations of progressive enhancement,
65.
     * which will add advanced interaction controls to any HTML table. For a
66.
     * full list of features please refer to
67.
     * [DataTables.net](href="http://datatables.net).
68.
     *
69.
     * Note that the `DataTable` object is not a global variable but is aliased
70.
     * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
71.
     * be  accessed.
72.
     *
73.
     *  @class
74.
     *  @param {object} [init={}] Configuration object for DataTables. Options
75.
     *    are defined by {@link DataTable.defaults}
76.
     *  @requires jQuery 1.7+
77.
     *
78.
     *  @example
79.
     *    // Basic initialisation
80.
     *    $(document).ready( function {
81.
     *      $('#example').dataTable();
82.
     *    } );
83.
     *
84.
     *  @example
85.
     *    // Initialisation with configuration options - in this case, disable
86.
     *    // pagination and sorting.
87.
     *    $(document).ready( function {
88.
     *      $('#example').dataTable( {
89.
     *        "paginate": false,
90.
     *        "sort": false
91.
     *      } );
92.
     *    } );
93.
     */
94.
    var DataTable = function ( options )
95.
    {
96.
        /**
97.
         * Perform a jQuery selector action on the table's TR elements (from the tbody) and
98.
         * return the resulting jQuery object.
99.
         *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
100.
         *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
101.
         *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
102.
         *    criterion ("applied") or all TR elements (i.e. no filter).
103.
         *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
104.
         *    Can be either 'current', whereby the current sorting of the table is used, or
105.
         *    'original' whereby the original order the data was read into the table is used.
106.
         *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
107.
         *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
108.
         *    'current' and filter is 'applied', regardless of what they might be given as.
109.
         *  @returns {object} jQuery object, filtered by the given selector.
110.
         *  @dtopt API
111.
         *  @deprecated Since v1.10
112.
         *
113.
         *  @example
114.
         *    $(document).ready(function() {
115.
         *      var oTable = $('#example').dataTable();
116.
         *
117.
         *      // Highlight every second row
118.
         *      oTable.$('tr:odd').css('backgroundColor', 'blue');
119.
         *    } );
120.
         *
121.
         *  @example
122.
         *    $(document).ready(function() {
123.
         *      var oTable = $('#example').dataTable();
124.
         *
125.
         *      // Filter to rows with 'Webkit' in them, add a background colour and then
126.
         *      // remove the filter, thus highlighting the 'Webkit' rows only.
127.
         *      oTable.fnFilter('Webkit');
128.
         *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
129.
         *      oTable.fnFilter('');
130.
         *    } );
131.
         */
132.
        this.$ = function ( sSelector, oOpts )
133.
        {
134.
            return this.api(true).$( sSelector, oOpts );
135.
        };
136.
        
137.
        
138.
        /**
139.
         * Almost identical to $ in operation, but in this case returns the data for the matched
140.
         * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
141.
         * rather than any descendants, so the data can be obtained for the row/cell. If matching
142.
         * rows are found, the data returned is the original data array/object that was used to
143.
         * create the row (or a generated array if from a DOM source).
144.
         *
145.
         * This method is often useful in-combination with $ where both functions are given the
146.
         * same parameters and the array indexes will match identically.
147.
         *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
148.
         *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
149.
         *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
150.
         *    criterion ("applied") or all elements (i.e. no filter).
151.
         *  @param {string} [oOpts.order=current] Order of the data in the processed array.
152.
         *    Can be either 'current', whereby the current sorting of the table is used, or
153.
         *    'original' whereby the original order the data was read into the table is used.
154.
         *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
155.
         *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
156.
         *    'current' and filter is 'applied', regardless of what they might be given as.
157.
         *  @returns {array} Data for the matched elements. If any elements, as a result of the
158.
         *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
159.
         *    entry in the array.
160.
         *  @dtopt API
161.
         *  @deprecated Since v1.10
162.
         *
163.
         *  @example
164.
         *    $(document).ready(function() {
165.
         *      var oTable = $('#example').dataTable();
166.
         *
167.
         *      // Get the data from the first row in the table
168.
         *      var data = oTable._('tr:first');
169.
         *
170.
         *      // Do something useful with the data
171.
         *      alert( "First cell is: "+data[0] );
172.
         *    } );
173.
         *
174.
         *  @example
175.
         *    $(document).ready(function() {
176.
         *      var oTable = $('#example').dataTable();
177.
         *
178.
         *      // Filter to 'Webkit' and get all data for
179.
         *      oTable.fnFilter('Webkit');
180.
         *      var data = oTable._('tr', {"search": "applied"});
181.
         *
182.
         *      // Do something with the data
183.
         *      alert( data.length+" rows matched the search" );
184.
         *    } );
185.
         */
186.
        this._ = function ( sSelector, oOpts )
187.
        {
188.
            return this.api(true).rows( sSelector, oOpts ).data();
189.
        };
190.
        
191.
        
192.
        /**
193.
         * Create a DataTables Api instance, with the currently selected tables for
194.
         * the Api's context.
195.
         * @param {boolean} [traditional=false] Set the API instance's context to be
196.
         *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
197.
         *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
198.
         *   or if all tables captured in the jQuery object should be used.
199.
         * @return {DataTables.Api}
200.
         */
201.
        this.api = function ( traditional )
202.
        {
203.
            return traditional ?
204.
                new _Api(
205.
                    _fnSettingsFromNode( this[ _ext.iApiIndex ] )
206.
                ) :
207.
                new _Api( this );
208.
        };
209.
        
210.
        
211.
        /**
212.
         * Add a single new row or multiple rows of data to the table. Please note
213.
         * that this is suitable for client-side processing only - if you are using
214.
         * server-side processing (i.e. "bServerSide": true), then to add data, you
215.
         * must add it to the data source, i.e. the server-side, through an Ajax call.
216.
         *  @param {array|object} data The data to be added to the table. This can be:
217.
         *    <ul>
218.
         *      <li>1D array of data - add a single row with the data provided</li>
219.
         *      <li>2D array of arrays - add multiple rows in a single call</li>
220.
         *      <li>object - data object when using <i>mData</i></li>
221.
         *      <li>array of objects - multiple data objects when using <i>mData</i></li>
222.
         *    </ul>
223.
         *  @param {bool} [redraw=true] redraw the table or not
224.
         *  @returns {array} An array of integers, representing the list of indexes in
225.
         *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
226.
         *    the table.
227.
         *  @dtopt API
228.
         *  @deprecated Since v1.10
229.
         *
230.
         *  @example
231.
         *    // Global var for counter
232.
         *    var giCount = 2;
233.
         *
234.
         *    $(document).ready(function() {
235.
         *      $('#example').dataTable();
236.
         *    } );
237.
         *
238.
         *    function fnClickAddRow() {
239.
         *      $('#example').dataTable().fnAddData( [
240.
         *        giCount+".1",
241.
         *        giCount+".2",
242.
         *        giCount+".3",
243.
         *        giCount+".4" ]
244.
         *      );
245.
         *
246.
         *      giCount++;
247.
         *    }
248.
         */
249.
        this.fnAddData = function( data, redraw )
250.
        {
251.
            var api = this.api( true );
252.
        
253.
            /* Check if we want to add multiple rows or not */
254.
            var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
255.
                api.rows.add( data ) :
256.
                api.row.add( data );
257.
        
258.
            if ( redraw === undefined || redraw ) {
259.
                api.draw();
260.
            }
261.
        
262.
            return rows.flatten().toArray();
263.
        };
264.
        
265.
        
266.
        /**
267.
         * This function will make DataTables recalculate the column sizes, based on the data
268.
         * contained in the table and the sizes applied to the columns (in the DOM, CSS or
269.
         * through the sWidth parameter). This can be useful when the width of the table's
270.
         * parent element changes (for example a window resize).
271.
         *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
272.
         *  @dtopt API
273.
         *  @deprecated Since v1.10
274.
         *
275.
         *  @example
276.
         *    $(document).ready(function() {
277.
         *      var oTable = $('#example').dataTable( {
278.
         *        "sScrollY": "200px",
279.
         *        "bPaginate": false
280.
         *      } );
281.
         *
282.
         *      $(window).on('resize', function () {
283.
         *        oTable.fnAdjustColumnSizing();
284.
         *      } );
285.
         *    } );
286.
         */
287.
        this.fnAdjustColumnSizing = function ( bRedraw )
288.
        {
289.
            var api = this.api( true ).columns.adjust();
290.
            var settings = api.settings()[0];
291.
            var scroll = settings.oScroll;
292.
        
293.
            if ( bRedraw === undefined || bRedraw ) {
294.
                api.draw( false );
295.
            }
296.
            else if ( scroll.sX !== "" || scroll.sY !== "" ) {
297.
                /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
298.
                _fnScrollDraw( settings );
299.
            }
300.
        };
301.
        
302.
        
303.
        /**
304.
         * Quickly and simply clear a table
305.
         *  @param {bool} [bRedraw=true] redraw the table or not
306.
         *  @dtopt API
307.
         *  @deprecated Since v1.10
308.
         *
309.
         *  @example
310.
         *    $(document).ready(function() {
311.
         *      var oTable = $('#example').dataTable();
312.
         *
313.
         *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
314.
         *      oTable.fnClearTable();
315.
         *    } );
316.
         */
317.
        this.fnClearTable = function( bRedraw )
318.
        {
319.
            var api = this.api( true ).clear();
320.
        
321.
            if ( bRedraw === undefined || bRedraw ) {
322.
                api.draw();
323.
            }
324.
        };
325.
        
326.
        
327.
        /**
328.
         * The exact opposite of 'opening' a row, this function will close any rows which
329.
         * are currently 'open'.
330.
         *  @param {node} nTr the table row to 'close'
331.
         *  @returns {int} 0 on success, or 1 if failed (can't find the row)
332.
         *  @dtopt API
333.
         *  @deprecated Since v1.10
334.
         *
335.
         *  @example
336.
         *    $(document).ready(function() {
337.
         *      var oTable;
338.
         *
339.
         *      // 'open' an information row when a row is clicked on
340.
         *      $('#example tbody tr').click( function () {
341.
         *        if ( oTable.fnIsOpen(this) ) {
342.
         *          oTable.fnClose( this );
343.
         *        } else {
344.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
345.
         *        }
346.
         *      } );
347.
         *
348.
         *      oTable = $('#example').dataTable();
349.
         *    } );
350.
         */
351.
        this.fnClose = function( nTr )
352.
        {
353.
            this.api( true ).row( nTr ).child.hide();
354.
        };
355.
        
356.
        
357.
        /**
358.
         * Remove a row for the table
359.
         *  @param {mixed} target The index of the row from aoData to be deleted, or
360.
         *    the TR element you want to delete
361.
         *  @param {function|null} [callBack] Callback function
362.
         *  @param {bool} [redraw=true] Redraw the table or not
363.
         *  @returns {array} The row that was deleted
364.
         *  @dtopt API
365.
         *  @deprecated Since v1.10
366.
         *
367.
         *  @example
368.
         *    $(document).ready(function() {
369.
         *      var oTable = $('#example').dataTable();
370.
         *
371.
         *      // Immediately remove the first row
372.
         *      oTable.fnDeleteRow( 0 );
373.
         *    } );
374.
         */
375.
        this.fnDeleteRow = function( target, callback, redraw )
376.
        {
377.
            var api = this.api( true );
378.
            var rows = api.rows( target );
379.
            var settings = rows.settings()[0];
380.
            var data = settings.aoData[ rows[0][0] ];
381.
        
382.
            rows.remove();
383.
        
384.
            if ( callback ) {
385.
                callback.call( this, settings, data );
386.
            }
387.
        
388.
            if ( redraw === undefined || redraw ) {
389.
                api.draw();
390.
            }
391.
        
392.
            return data;
393.
        };
394.
        
395.
        
396.
        /**
397.
         * Restore the table to it's original state in the DOM by removing all of DataTables
398.
         * enhancements, alterations to the DOM structure of the table and event listeners.
399.
         *  @param {boolean} [remove=false] Completely remove the table from the DOM
400.
         *  @dtopt API
401.
         *  @deprecated Since v1.10
402.
         *
403.
         *  @example
404.
         *    $(document).ready(function() {
405.
         *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
406.
         *      var oTable = $('#example').dataTable();
407.
         *      oTable.fnDestroy();
408.
         *    } );
409.
         */
410.
        this.fnDestroy = function ( remove )
411.
        {
412.
            this.api( true ).destroy( remove );
413.
        };
414.
        
415.
        
416.
        /**
417.
         * Redraw the table
418.
         *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
419.
         *  @dtopt API
420.
         *  @deprecated Since v1.10
421.
         *
422.
         *  @example
423.
         *    $(document).ready(function() {
424.
         *      var oTable = $('#example').dataTable();
425.
         *
426.
         *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
427.
         *      oTable.fnDraw();
428.
         *    } );
429.
         */
430.
        this.fnDraw = function( complete )
431.
        {
432.
            // Note that this isn't an exact match to the old call to _fnDraw - it takes
433.
            // into account the new data, but can hold position.
434.
            this.api( true ).draw( complete );
435.
        };
436.
        
437.
        
438.
        /**
439.
         * Filter the input based on data
440.
         *  @param {string} sInput String to filter the table on
441.
         *  @param {int|null} [iColumn] Column to limit filtering to
442.
         *  @param {bool} [bRegex=false] Treat as regular expression or not
443.
         *  @param {bool} [bSmart=true] Perform smart filtering or not
444.
         *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
445.
         *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
446.
         *  @dtopt API
447.
         *  @deprecated Since v1.10
448.
         *
449.
         *  @example
450.
         *    $(document).ready(function() {
451.
         *      var oTable = $('#example').dataTable();
452.
         *
453.
         *      // Sometime later - filter...
454.
         *      oTable.fnFilter( 'test string' );
455.
         *    } );
456.
         */
457.
        this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
458.
        {
459.
            var api = this.api( true );
460.
        
461.
            if ( iColumn === null || iColumn === undefined ) {
462.
                api.search( sInput, bRegex, bSmart, bCaseInsensitive );
463.
            }
464.
            else {
465.
                api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
466.
            }
467.
        
468.
            api.draw();
469.
        };
470.
        
471.
        
472.
        /**
473.
         * Get the data for the whole table, an individual row or an individual cell based on the
474.
         * provided parameters.
475.
         *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
476.
         *    a TR node then the data source for the whole row will be returned. If given as a
477.
         *    TD/TH cell node then iCol will be automatically calculated and the data for the
478.
         *    cell returned. If given as an integer, then this is treated as the aoData internal
479.
         *    data index for the row (see fnGetPosition) and the data for that row used.
480.
         *  @param {int} [col] Optional column index that you want the data of.
481.
         *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
482.
         *    returned. If mRow is defined, just data for that row, and is iCol is
483.
         *    defined, only data for the designated cell is returned.
484.
         *  @dtopt API
485.
         *  @deprecated Since v1.10
486.
         *
487.
         *  @example
488.
         *    // Row data
489.
         *    $(document).ready(function() {
490.
         *      oTable = $('#example').dataTable();
491.
         *
492.
         *      oTable.$('tr').click( function () {
493.
         *        var data = oTable.fnGetData( this );
494.
         *        // ... do something with the array / object of data for the row
495.
         *      } );
496.
         *    } );
497.
         *
498.
         *  @example
499.
         *    // Individual cell data
500.
         *    $(document).ready(function() {
501.
         *      oTable = $('#example').dataTable();
502.
         *
503.
         *      oTable.$('td').click( function () {
504.
         *        var sData = oTable.fnGetData( this );
505.
         *        alert( 'The cell clicked on had the value of '+sData );
506.
         *      } );
507.
         *    } );
508.
         */
509.
        this.fnGetData = function( src, col )
510.
        {
511.
            var api = this.api( true );
512.
        
513.
            if ( src !== undefined ) {
514.
                var type = src.nodeName ? src.nodeName.toLowerCase() : '';
515.
        
516.
                return col !== undefined || type == 'td' || type == 'th' ?
517.
                    api.cell( src, col ).data() :
518.
                    api.row( src ).data() || null;
519.
            }
520.
        
521.
            return api.data().toArray();
522.
        };
523.
        
524.
        
525.
        /**
526.
         * Get an array of the TR nodes that are used in the table's body. Note that you will
527.
         * typically want to use the '$' API method in preference to this as it is more
528.
         * flexible.
529.
         *  @param {int} [iRow] Optional row index for the TR element you want
530.
         *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
531.
         *    in the table's body, or iRow is defined, just the TR element requested.
532.
         *  @dtopt API
533.
         *  @deprecated Since v1.10
534.
         *
535.
         *  @example
536.
         *    $(document).ready(function() {
537.
         *      var oTable = $('#example').dataTable();
538.
         *
539.
         *      // Get the nodes from the table
540.
         *      var nNodes = oTable.fnGetNodes( );
541.
         *    } );
542.
         */
543.
        this.fnGetNodes = function( iRow )
544.
        {
545.
            var api = this.api( true );
546.
        
547.
            return iRow !== undefined ?
548.
                api.row( iRow ).node() :
549.
                api.rows().nodes().flatten().toArray();
550.
        };
551.
        
552.
        
553.
        /**
554.
         * Get the array indexes of a particular cell from it's DOM element
555.
         * and column index including hidden columns
556.
         *  @param {node} node this can either be a TR, TD or TH in the table's body
557.
         *  @returns {int} If nNode is given as a TR, then a single index is returned, or
558.
         *    if given as a cell, an array of [row index, column index (visible),
559.
         *    column index (all)] is given.
560.
         *  @dtopt API
561.
         *  @deprecated Since v1.10
562.
         *
563.
         *  @example
564.
         *    $(document).ready(function() {
565.
         *      $('#example tbody td').click( function () {
566.
         *        // Get the position of the current data from the node
567.
         *        var aPos = oTable.fnGetPosition( this );
568.
         *
569.
         *        // Get the data array for this row
570.
         *        var aData = oTable.fnGetData( aPos[0] );
571.
         *
572.
         *        // Update the data array and return the value
573.
         *        aData[ aPos[1] ] = 'clicked';
574.
         *        this.innerHTML = 'clicked';
575.
         *      } );
576.
         *
577.
         *      // Init DataTables
578.
         *      oTable = $('#example').dataTable();
579.
         *    } );
580.
         */
581.
        this.fnGetPosition = function( node )
582.
        {
583.
            var api = this.api( true );
584.
            var nodeName = node.nodeName.toUpperCase();
585.
        
586.
            if ( nodeName == 'TR' ) {
587.
                return api.row( node ).index();
588.
            }
589.
            else if ( nodeName == 'TD' || nodeName == 'TH' ) {
590.
                var cell = api.cell( node ).index();
591.
        
592.
                return [
593.
                    cell.row,
594.
                    cell.columnVisible,
595.
                    cell.column
596.
                ];
597.
            }
598.
            return null;
599.
        };
600.
        
601.
        
602.
        /**
603.
         * Check to see if a row is 'open' or not.
604.
         *  @param {node} nTr the table row to check
605.
         *  @returns {boolean} true if the row is currently open, false otherwise
606.
         *  @dtopt API
607.
         *  @deprecated Since v1.10
608.
         *
609.
         *  @example
610.
         *    $(document).ready(function() {
611.
         *      var oTable;
612.
         *
613.
         *      // 'open' an information row when a row is clicked on
614.
         *      $('#example tbody tr').click( function () {
615.
         *        if ( oTable.fnIsOpen(this) ) {
616.
         *          oTable.fnClose( this );
617.
         *        } else {
618.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
619.
         *        }
620.
         *      } );
621.
         *
622.
         *      oTable = $('#example').dataTable();
623.
         *    } );
624.
         */
625.
        this.fnIsOpen = function( nTr )
626.
        {
627.
            return this.api( true ).row( nTr ).child.isShown();
628.
        };
629.
        
630.
        
631.
        /**
632.
         * This function will place a new row directly after a row which is currently
633.
         * on display on the page, with the HTML contents that is passed into the
634.
         * function. This can be used, for example, to ask for confirmation that a
635.
         * particular record should be deleted.
636.
         *  @param {node} nTr The table row to 'open'
637.
         *  @param {string|node|jQuery} mHtml The HTML to put into the row
638.
         *  @param {string} sClass Class to give the new TD cell
639.
         *  @returns {node} The row opened. Note that if the table row passed in as the
640.
         *    first parameter, is not found in the table, this method will silently
641.
         *    return.
642.
         *  @dtopt API
643.
         *  @deprecated Since v1.10
644.
         *
645.
         *  @example
646.
         *    $(document).ready(function() {
647.
         *      var oTable;
648.
         *
649.
         *      // 'open' an information row when a row is clicked on
650.
         *      $('#example tbody tr').click( function () {
651.
         *        if ( oTable.fnIsOpen(this) ) {
652.
         *          oTable.fnClose( this );
653.
         *        } else {
654.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
655.
         *        }
656.
         *      } );
657.
         *
658.
         *      oTable = $('#example').dataTable();
659.
         *    } );
660.
         */
661.
        this.fnOpen = function( nTr, mHtml, sClass )
662.
        {
663.
            return this.api( true )
664.
                .row( nTr )
665.
                .child( mHtml, sClass )
666.
                .show()
667.
                .child()[0];
668.
        };
669.
        
670.
        
671.
        /**
672.
         * Change the pagination - provides the internal logic for pagination in a simple API
673.
         * function. With this function you can have a DataTables table go to the next,
674.
         * previous, first or last pages.
675.
         *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
676.
         *    or page number to jump to (integer), note that page 0 is the first page.
677.
         *  @param {bool} [bRedraw=true] Redraw the table or not
678.
         *  @dtopt API
679.
         *  @deprecated Since v1.10
680.
         *
681.
         *  @example
682.
         *    $(document).ready(function() {
683.
         *      var oTable = $('#example').dataTable();
684.
         *      oTable.fnPageChange( 'next' );
685.
         *    } );
686.
         */
687.
        this.fnPageChange = function ( mAction, bRedraw )
688.
        {
689.
            var api = this.api( true ).page( mAction );
690.
        
691.
            if ( bRedraw === undefined || bRedraw ) {
692.
                api.draw(false);
693.
            }
694.
        };
695.
        
696.
        
697.
        /**
698.
         * Show a particular column
699.
         *  @param {int} iCol The column whose display should be changed
700.
         *  @param {bool} bShow Show (true) or hide (false) the column
701.
         *  @param {bool} [bRedraw=true] Redraw the table or not
702.
         *  @dtopt API
703.
         *  @deprecated Since v1.10
704.
         *
705.
         *  @example
706.
         *    $(document).ready(function() {
707.
         *      var oTable = $('#example').dataTable();
708.
         *
709.
         *      // Hide the second column after initialisation
710.
         *      oTable.fnSetColumnVis( 1, false );
711.
         *    } );
712.
         */
713.
        this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
714.
        {
715.
            var api = this.api( true ).column( iCol ).visible( bShow );
716.
        
717.
            if ( bRedraw === undefined || bRedraw ) {
718.
                api.columns.adjust().draw();
719.
            }
720.
        };
721.
        
722.
        
723.
        /**
724.
         * Get the settings for a particular table for external manipulation
725.
         *  @returns {object} DataTables settings object. See
726.
         *    {@link DataTable.models.oSettings}
727.
         *  @dtopt API
728.
         *  @deprecated Since v1.10
729.
         *
730.
         *  @example
731.
         *    $(document).ready(function() {
732.
         *      var oTable = $('#example').dataTable();
733.
         *      var oSettings = oTable.fnSettings();
734.
         *
735.
         *      // Show an example parameter from the settings
736.
         *      alert( oSettings._iDisplayStart );
737.
         *    } );
738.
         */
739.
        this.fnSettings = function()
740.
        {
741.
            return _fnSettingsFromNode( this[_ext.iApiIndex] );
742.
        };
743.
        
744.
        
745.
        /**
746.
         * Sort the table by a particular column
747.
         *  @param {int} iCol the data index to sort on. Note that this will not match the
748.
         *    'display index' if you have hidden data entries
749.
         *  @dtopt API
750.
         *  @deprecated Since v1.10
751.
         *
752.
         *  @example
753.
         *    $(document).ready(function() {
754.
         *      var oTable = $('#example').dataTable();
755.
         *
756.
         *      // Sort immediately with columns 0 and 1
757.
         *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
758.
         *    } );
759.
         */
760.
        this.fnSort = function( aaSort )
761.
        {
762.
            this.api( true ).order( aaSort ).draw();
763.
        };
764.
        
765.
        
766.
        /**
767.
         * Attach a sort listener to an element for a given column
768.
         *  @param {node} nNode the element to attach the sort listener to
769.
         *  @param {int} iColumn the column that a click on this node will sort on
770.
         *  @param {function} [fnCallback] callback function when sort is run
771.
         *  @dtopt API
772.
         *  @deprecated Since v1.10
773.
         *
774.
         *  @example
775.
         *    $(document).ready(function() {
776.
         *      var oTable = $('#example').dataTable();
777.
         *
778.
         *      // Sort on column 1, when 'sorter' is clicked on
779.
         *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
780.
         *    } );
781.
         */
782.
        this.fnSortListener = function( nNode, iColumn, fnCallback )
783.
        {
784.
            this.api( true ).order.listener( nNode, iColumn, fnCallback );
785.
        };
786.
        
787.
        
788.
        /**
789.
         * Update a table cell or row - this method will accept either a single value to
790.
         * update the cell with, an array of values with one element for each column or
791.
         * an object in the same format as the original data source. The function is
792.
         * self-referencing in order to make the multi column updates easier.
793.
         *  @param {object|array|string} mData Data to update the cell/row with
794.
         *  @param {node|int} mRow TR element you want to update or the aoData index
795.
         *  @param {int} [iColumn] The column to update, give as null or undefined to
796.
         *    update a whole row.
797.
         *  @param {bool} [bRedraw=true] Redraw the table or not
798.
         *  @param {bool} [bAction=true] Perform pre-draw actions or not
799.
         *  @returns {int} 0 on success, 1 on error
800.
         *  @dtopt API
801.
         *  @deprecated Since v1.10
802.
         *
803.
         *  @example
804.
         *    $(document).ready(function() {
805.
         *      var oTable = $('#example').dataTable();
806.
         *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
807.
         *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
808.
         *    } );
809.
         */
810.
        this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
811.
        {
812.
            var api = this.api( true );
813.
        
814.
            if ( iColumn === undefined || iColumn === null ) {
815.
                api.row( mRow ).data( mData );
816.
            }
817.
            else {
818.
                api.cell( mRow, iColumn ).data( mData );
819.
            }
820.
        
821.
            if ( bAction === undefined || bAction ) {
822.
                api.columns.adjust();
823.
            }
824.
        
825.
            if ( bRedraw === undefined || bRedraw ) {
826.
                api.draw();
827.
            }
828.
            return 0;
829.
        };
830.
        
831.
        
832.
        /**
833.
         * Provide a common method for plug-ins to check the version of DataTables being used, in order
834.
         * to ensure compatibility.
835.
         *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
836.
         *    formats "X" and "X.Y" are also acceptable.
837.
         *  @returns {boolean} true if this version of DataTables is greater or equal to the required
838.
         *    version, or false if this version of DataTales is not suitable
839.
         *  @method
840.
         *  @dtopt API
841.
         *  @deprecated Since v1.10
842.
         *
843.
         *  @example
844.
         *    $(document).ready(function() {
845.
         *      var oTable = $('#example').dataTable();
846.
         *      alert( oTable.fnVersionCheck( '1.9.0' ) );
847.
         *    } );
848.
         */
849.
        this.fnVersionCheck = _ext.fnVersionCheck;
850.
        
851.
 
852.
        var _that = this;
853.
        var emptyInit = options === undefined;
854.
        var len = this.length;
855.
 
856.
        if ( emptyInit ) {
857.
            options = {};
858.
        }
859.
 
860.
        this.oApi = this.internal = _ext.internal;
861.
 
862.
        // Extend with old style plug-in API methods
863.
        for ( var fn in DataTable.ext.internal ) {
864.
            if ( fn ) {
865.
                this[fn] = _fnExternApiFunc(fn);
866.
            }
867.
        }
868.
 
869.
        this.each(function() {
870.
            // For each initialisation we want to give it a clean initialisation
871.
            // object that can be bashed around
872.
            var o = {};
873.
            var oInit = len > 1 ? // optimisation for single table case
874.
                _fnExtend( o, options, true ) :
875.
                options;
876.
 
877.
            /*global oInit,_that,emptyInit*/
878.
            var i=0, iLen, j, jLen, k, kLen;
879.
            var sId = this.getAttribute( 'id' );
880.
            var bInitHandedOff = false;
881.
            var defaults = DataTable.defaults;
882.
            var $this = $(this);
883.
            
884.
            
885.
            /* Sanity check */
886.
            if ( this.nodeName.toLowerCase() != 'table' )
887.
            {
888.
                _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
889.
                return;
890.
            }
891.
            
892.
            /* Backwards compatibility for the defaults */
893.
            _fnCompatOpts( defaults );
894.
            _fnCompatCols( defaults.column );
895.
            
896.
            /* Convert the camel-case defaults to Hungarian */
897.
            _fnCamelToHungarian( defaults, defaults, true );
898.
            _fnCamelToHungarian( defaults.column, defaults.column, true );
899.
            
900.
            /* Setting up the initialisation object */
901.
            _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );
902.
            
903.
            
904.
            
905.
            /* Check to see if we are re-initialising a table */
906.
            var allSettings = DataTable.settings;
907.
            for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
908.
            {
909.
                var s = allSettings[i];
910.
            
911.
                /* Base check on table node */
912.
                if (
913.
                    s.nTable == this ||
914.
                    (s.nTHead && s.nTHead.parentNode == this) ||
915.
                    (s.nTFoot && s.nTFoot.parentNode == this)
916.
                ) {
917.
                    var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
918.
                    var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
919.
            
920.
                    if ( emptyInit || bRetrieve )
921.
                    {
922.
                        return s.oInstance;
923.
                    }
924.
                    else if ( bDestroy )
925.
                    {
926.
                        s.oInstance.fnDestroy();
927.
                        break;
928.
                    }
929.
                    else
930.
                    {
931.
                        _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
932.
                        return;
933.
                    }
934.
                }
935.
            
936.
                /* If the element we are initialising has the same ID as a table which was previously
937.
                 * initialised, but the table nodes don't match (from before) then we destroy the old
938.
                 * instance by simply deleting it. This is under the assumption that the table has been
939.
                 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
940.
                 */
941.
                if ( s.sTableId == this.id )
942.
                {
943.
                    allSettings.splice( i, 1 );
944.
                    break;
945.
                }
946.
            }
947.
            
948.
            /* Ensure the table has an ID - required for accessibility */
949.
            if ( sId === null || sId === "" )
950.
            {
951.
                sId = "DataTables_Table_"+(DataTable.ext._unique++);
952.
                this.id = sId;
953.
            }
954.
            
955.
            /* Create the settings object for this table and set some of the default parameters */
956.
            var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
957.
                "sDestroyWidth": $this[0].style.width,
958.
                "sInstance":     sId,
959.
                "sTableId":      sId
960.
            } );
961.
            oSettings.nTable = this;
962.
            oSettings.oApi   = _that.internal;
963.
            oSettings.oInit  = oInit;
964.
            
965.
            allSettings.push( oSettings );
966.
            
967.
            // Need to add the instance after the instance after the settings object has been added
968.
            // to the settings array, so we can self reference the table instance if more than one
969.
            oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
970.
            
971.
            // Backwards compatibility, before we apply all the defaults
972.
            _fnCompatOpts( oInit );
973.
            _fnLanguageCompat( oInit.oLanguage );
974.
            
975.
            // If the length menu is given, but the init display length is not, use the length menu
976.
            if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
977.
            {
978.
                oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
979.
                    oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
980.
            }
981.
            
982.
            // Apply the defaults and init options to make a single init object will all
983.
            // options defined from defaults and instance options.
984.
            oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
985.
            
986.
            
987.
            // Map the initialisation options onto the settings object
988.
            _fnMap( oSettings.oFeatures, oInit, [
989.
                "bPaginate",
990.
                "bLengthChange",
991.
                "bFilter",
992.
                "bSort",
993.
                "bSortMulti",
994.
                "bInfo",
995.
                "bProcessing",
996.
                "bAutoWidth",
997.
                "bSortClasses",
998.
                "bServerSide",
999.
                "bDeferRender"
1000.
            ] );
1001.
            _fnMap( oSettings, oInit, [
1002.
                "asStripeClasses",
1003.
                "ajax",
1004.
                "fnServerData",
1005.
                "fnFormatNumber",
1006.
                "sServerMethod",
1007.
                "aaSorting",
1008.
                "aaSortingFixed",
1009.
                "aLengthMenu",
1010.
                "sPaginationType",
1011.
                "sAjaxSource",
1012.
                "sAjaxDataProp",
1013.
                "iStateDuration",
1014.
                "sDom",
1015.
                "bSortCellsTop",
1016.
                "iTabIndex",
1017.
                "fnStateLoadCallback",
1018.
                "fnStateSaveCallback",
1019.
                "renderer",
1020.
                "searchDelay",
1021.
                "rowId",
1022.
                [ "iCookieDuration", "iStateDuration" ], // backwards compat
1023.
                [ "oSearch", "oPreviousSearch" ],
1024.
                [ "aoSearchCols", "aoPreSearchCols" ],
1025.
                [ "iDisplayLength", "_iDisplayLength" ]
1026.
            ] );
1027.
            _fnMap( oSettings.oScroll, oInit, [
1028.
                [ "sScrollX", "sX" ],
1029.
                [ "sScrollXInner", "sXInner" ],
1030.
                [ "sScrollY", "sY" ],
1031.
                [ "bScrollCollapse", "bCollapse" ]
1032.
            ] );
1033.
            _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
1034.
            
1035.
            /* Callback functions which are array driven */
1036.
            _fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
1037.
            _fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
1038.
            _fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
1039.
            _fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
1040.
            _fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
1041.
            _fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
1042.
            _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
1043.
            _fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
1044.
            _fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
1045.
            _fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
1046.
            _fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
1047.
            
1048.
            oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
1049.
            
1050.
            /* Browser support detection */
1051.
            _fnBrowserDetect( oSettings );
1052.
            
1053.
            var oClasses = oSettings.oClasses;
1054.
            
1055.
            $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
1056.
            $this.addClass( oClasses.sTable );
1057.
            
1058.
            
1059.
            if ( oSettings.iInitDisplayStart === undefined )
1060.
            {
1061.
                /* Display start point, taking into account the save saving */
1062.
                oSettings.iInitDisplayStart = oInit.iDisplayStart;
1063.
                oSettings._iDisplayStart = oInit.iDisplayStart;
1064.
            }
1065.
            
1066.
            if ( oInit.iDeferLoading !== null )
1067.
            {
1068.
                oSettings.bDeferLoading = true;
1069.
                var tmp = $.isArray( oInit.iDeferLoading );
1070.
                oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
1071.
                oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
1072.
            }
1073.
            
1074.
            /* Language definitions */
1075.
            var oLanguage = oSettings.oLanguage;
1076.
            $.extend( true, oLanguage, oInit.oLanguage );
1077.
            
1078.
            if ( oLanguage.sUrl )
1079.
            {
1080.
                /* Get the language definitions from a file - because this Ajax call makes the language
1081.
                 * get async to the remainder of this function we use bInitHandedOff to indicate that
1082.
                 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
1083.
                 */
1084.
                $.ajax( {
1085.
                    dataType: 'json',
1086.
                    url: oLanguage.sUrl,
1087.
                    success: function ( json ) {
1088.
                        _fnLanguageCompat( json );
1089.
                        _fnCamelToHungarian( defaults.oLanguage, json );
1090.
                        $.extend( true, oLanguage, json );
1091.
                        _fnInitialise( oSettings );
1092.
                    },
1093.
                    error: function () {
1094.
                        // Error occurred loading language file, continue on as best we can
1095.
                        _fnInitialise( oSettings );
1096.
                    }
1097.
                } );
1098.
                bInitHandedOff = true;
1099.
            }
1100.
            
1101.
            /*
1102.
             * Stripes
1103.
             */
1104.
            if ( oInit.asStripeClasses === null )
1105.
            {
1106.
                oSettings.asStripeClasses =[
1107.
                    oClasses.sStripeOdd,
1108.
                    oClasses.sStripeEven
1109.
                ];
1110.
            }
1111.
            
1112.
            /* Remove row stripe classes if they are already on the table row */
1113.
            var stripeClasses = oSettings.asStripeClasses;
1114.
            var rowOne = $this.children('tbody').find('tr').eq(0);
1115.
            if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
1116.
                return rowOne.hasClass(el);
1117.
            } ) ) !== -1 ) {
1118.
                $('tbody tr', this).removeClass( stripeClasses.join(' ') );
1119.
                oSettings.asDestroyStripes = stripeClasses.slice();
1120.
            }
1121.
            
1122.
            /*
1123.
             * Columns
1124.
             * See if we should load columns automatically or use defined ones
1125.
             */
1126.
            var anThs = [];
1127.
            var aoColumnsInit;
1128.
            var nThead = this.getElementsByTagName('thead');
1129.
            if ( nThead.length !== 0 )
1130.
            {
1131.
                _fnDetectHeader( oSettings.aoHeader, nThead[0] );
1132.
                anThs = _fnGetUniqueThs( oSettings );
1133.
            }
1134.
            
1135.
            /* If not given a column array, generate one with nulls */
1136.
            if ( oInit.aoColumns === null )
1137.
            {
1138.
                aoColumnsInit = [];
1139.
                for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
1140.
                {
1141.
                    aoColumnsInit.push( null );
1142.
                }
1143.
            }
1144.
            else
1145.
            {
1146.
                aoColumnsInit = oInit.aoColumns;
1147.
            }
1148.
            
1149.
            /* Add the columns */
1150.
            for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
1151.
            {
1152.
                _fnAddColumn( oSettings, anThs ? anThs[i] : null );
1153.
            }
1154.
            
1155.
            /* Apply the column definitions */
1156.
            _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
1157.
                _fnColumnOptions( oSettings, iCol, oDef );
1158.
            } );
1159.
            
1160.
            /* HTML5 attribute detection - build an mData object automatically if the
1161.
             * attributes are found
1162.
             */
1163.
            if ( rowOne.length ) {
1164.
                var a = function ( cell, name ) {
1165.
                    return cell.getAttribute( 'data-'+name ) !== null ? name : null;
1166.
                };
1167.
            
1168.
                $( rowOne[0] ).children('th, td').each( function (i, cell) {
1169.
                    var col = oSettings.aoColumns[i];
1170.
            
1171.
                    if ( col.mData === i ) {
1172.
                        var sort = a( cell, 'sort' ) || a( cell, 'order' );
1173.
                        var filter = a( cell, 'filter' ) || a( cell, 'search' );
1174.
            
1175.
                        if ( sort !== null || filter !== null ) {
1176.
                            col.mData = {
1177.
                                _:      i+'.display',
1178.
                                sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
1179.
                                type:   sort !== null   ? i+'.@data-'+sort   : undefined,
1180.
                                filter: filter !== null ? i+'.@data-'+filter : undefined
1181.
                            };
1182.
            
1183.
                            _fnColumnOptions( oSettings, i );
1184.
                        }
1185.
                    }
1186.
                } );
1187.
            }
1188.
            
1189.
            var features = oSettings.oFeatures;
1190.
            var loadedInit = function () {
1191.
                /*
1192.
                 * Sorting
1193.
                 * @todo For modularisation (1.11) this needs to do into a sort start up handler
1194.
                 */
1195.
            
1196.
                // If aaSorting is not defined, then we use the first indicator in asSorting
1197.
                // in case that has been altered, so the default sort reflects that option
1198.
                if ( oInit.aaSorting === undefined ) {
1199.
                    var sorting = oSettings.aaSorting;
1200.
                    for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
1201.
                        sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1202.
                    }
1203.
                }
1204.
            
1205.
                /* Do a first pass on the sorting classes (allows any size changes to be taken into
1206.
                 * account, and also will apply sorting disabled classes if disabled
1207.
                 */
1208.
                _fnSortingClasses( oSettings );
1209.
            
1210.
                if ( features.bSort ) {
1211.
                    _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1212.
                        if ( oSettings.bSorted ) {
1213.
                            var aSort = _fnSortFlatten( oSettings );
1214.
                            var sortedColumns = {};
1215.
            
1216.
                            $.each( aSort, function (i, val) {
1217.
                                sortedColumns[ val.src ] = val.dir;
1218.
                            } );
1219.
            
1220.
                            _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
1221.
                            _fnSortAria( oSettings );
1222.
                        }
1223.
                    } );
1224.
                }
1225.
            
1226.
                _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1227.
                    if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
1228.
                        _fnSortingClasses( oSettings );
1229.
                    }
1230.
                }, 'sc' );
1231.
            
1232.
            
1233.
                /*
1234.
                 * Final init
1235.
                 * Cache the header, body and footer as required, creating them if needed
1236.
                 */
1237.
            
1238.
                // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1239.
                var captions = $this.children('caption').each( function () {
1240.
                    this._captionSide = $(this).css('caption-side');
1241.
                } );
1242.
            
1243.
                var thead = $this.children('thead');
1244.
                if ( thead.length === 0 ) {
1245.
                    thead = $('<thead/>').appendTo($this);
1246.
                }
1247.
                oSettings.nTHead = thead[0];
1248.
            
1249.
                var tbody = $this.children('tbody');
1250.
                if ( tbody.length === 0 ) {
1251.
                    tbody = $('<tbody/>').appendTo($this);
1252.
                }
1253.
                oSettings.nTBody = tbody[0];
1254.
            
1255.
                var tfoot = $this.children('tfoot');
1256.
                if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
1257.
                    // If we are a scrolling table, and no footer has been given, then we need to create
1258.
                    // a tfoot element for the caption element to be appended to
1259.
                    tfoot = $('<tfoot/>').appendTo($this);
1260.
                }
1261.
            
1262.
                if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
1263.
                    $this.addClass( oClasses.sNoFooter );
1264.
                }
1265.
                else if ( tfoot.length > 0 ) {
1266.
                    oSettings.nTFoot = tfoot[0];
1267.
                    _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
1268.
                }
1269.
            
1270.
                /* Check if there is data passing into the constructor */
1271.
                if ( oInit.aaData ) {
1272.
                    for ( i=0 ; i<oInit.aaData.length ; i++ ) {
1273.
                        _fnAddData( oSettings, oInit.aaData[ i ] );
1274.
                    }
1275.
                }
1276.
                else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
1277.
                    /* Grab the data from the page - only do this when deferred loading or no Ajax
1278.
                     * source since there is no point in reading the DOM data if we are then going
1279.
                     * to replace it with Ajax data
1280.
                     */
1281.
                    _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
1282.
                }
1283.
            
1284.
                /* Copy the data index array */
1285.
                oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1286.
            
1287.
                /* Initialisation complete - table can be drawn */
1288.
                oSettings.bInitialised = true;
1289.
            
1290.
                /* Check if we need to initialise the table (it might not have been handed off to the
1291.
                 * language processor)
1292.
                 */
1293.
                if ( bInitHandedOff === false ) {
1294.
                    _fnInitialise( oSettings );
1295.
                }
1296.
            };
1297.
            
1298.
            /* Must be done after everything which can be overridden by the state saving! */
1299.
            if ( oInit.bStateSave )
1300.
            {
1301.
                features.bStateSave = true;
1302.
                _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
1303.
                _fnLoadState( oSettings, oInit, loadedInit );
1304.
            }
1305.
            else {
1306.
                loadedInit();
1307.
            }
1308.
            
1309.
        } );
1310.
        _that = null;
1311.
        return this;
1312.
    };
1313.
 
1314.
    
1315.
    /*
1316.
     * It is useful to have variables which are scoped locally so only the
1317.
     * DataTables functions can access them and they don't leak into global space.
1318.
     * At the same time these functions are often useful over multiple files in the
1319.
     * core and API, so we list, or at least document, all variables which are used
1320.
     * by DataTables as private variables here. This also ensures that there is no
1321.
     * clashing of variable names and that they can easily referenced for reuse.
1322.
     */
1323.
    
1324.
    
1325.
    // Defined else where
1326.
    //  _selector_run
1327.
    //  _selector_opts
1328.
    //  _selector_first
1329.
    //  _selector_row_indexes
1330.
    
1331.
    var _ext; // DataTable.ext
1332.
    var _Api; // DataTable.Api
1333.
    var _api_register; // DataTable.Api.register
1334.
    var _api_registerPlural; // DataTable.Api.registerPlural
1335.
    
1336.
    var _re_dic = {};
1337.
    var _re_new_lines = /[\r\n\u2028]/g;
1338.
    var _re_html = /<.*?>/g;
1339.
    
1340.
    // This is not strict ISO8601 - Date.parse() is quite lax, although
1341.
    // implementations differ between browsers.
1342.
    var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1343.
    
1344.
    // Escape regular expression special characters
1345.
    var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
1346.
    
1347.
    // http://en.wikipedia.org/wiki/Foreign_exchange_market
1348.
    // - \u20BD - Russian ruble.
1349.
    // - \u20a9 - South Korean Won
1350.
    // - \u20BA - Turkish Lira
1351.
    // - \u20B9 - Indian Rupee
1352.
    // - R - Brazil (R$) and South Africa
1353.
    // - fr - Swiss Franc
1354.
    // - kr - Swedish krona, Norwegian krone and Danish krone
1355.
    // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1356.
    // - Ƀ - Bitcoin
1357.
    // - Ξ - Ethereum
1358.
    //   standards as thousands separators.
1359.
    var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
1360.
    
1361.
    
1362.
    var _empty = function ( d ) {
1363.
        return !d || d === true || d === '-' ? true : false;
1364.
    };
1365.
    
1366.
    
1367.
    var _intVal = function ( s ) {
1368.
        var integer = parseInt( s, 10 );
1369.
        return !isNaN(integer) && isFinite(s) ? integer : null;
1370.
    };
1371.
    
1372.
    // Convert from a formatted number with characters other than `.` as the
1373.
    // decimal place, to a Javascript number
1374.
    var _numToDecimal = function ( num, decimalPoint ) {
1375.
        // Cache created regular expressions for speed as this function is called often
1376.
        if ( ! _re_dic[ decimalPoint ] ) {
1377.
            _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
1378.
        }
1379.
        return typeof num === 'string' && decimalPoint !== '.' ?
1380.
            num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
1381.
            num;
1382.
    };
1383.
    
1384.
    
1385.
    var _isNumber = function ( d, decimalPoint, formatted ) {
1386.
        var strType = typeof d === 'string';
1387.
    
1388.
        // If empty return immediately so there must be a number if it is a
1389.
        // formatted string (this stops the string "k", or "kr", etc being detected
1390.
        // as a formatted number for currency
1391.
        if ( _empty( d ) ) {
1392.
            return true;
1393.
        }
1394.
    
1395.
        if ( decimalPoint && strType ) {
1396.
            d = _numToDecimal( d, decimalPoint );
1397.
        }
1398.
    
1399.
        if ( formatted && strType ) {
1400.
            d = d.replace( _re_formatted_numeric, '' );
1401.
        }
1402.
    
1403.
        return !isNaN( parseFloat(d) ) && isFinite( d );
1404.
    };
1405.
    
1406.
    
1407.
    // A string without HTML in it can be considered to be HTML still
1408.
    var _isHtml = function ( d ) {
1409.
        return _empty( d ) || typeof d === 'string';
1410.
    };
1411.
    
1412.
    
1413.
    var _htmlNumeric = function ( d, decimalPoint, formatted ) {
1414.
        if ( _empty( d ) ) {
1415.
            return true;
1416.
        }
1417.
    
1418.
        var html = _isHtml( d );
1419.
        return ! html ?
1420.
            null :
1421.
            _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
1422.
                true :
1423.
                null;
1424.
    };
1425.
    
1426.
    
1427.
    var _pluck = function ( a, prop, prop2 ) {
1428.
        var out = [];
1429.
        var i=0, ien=a.length;
1430.
    
1431.
        // Could have the test in the loop for slightly smaller code, but speed
1432.
        // is essential here
1433.
        if ( prop2 !== undefined ) {
1434.
            for ( ; i<ien ; i++ ) {
1435.
                if ( a[i] && a[i][ prop ] ) {
1436.
                    out.push( a[i][ prop ][ prop2 ] );
1437.
                }
1438.
            }
1439.
        }
1440.
        else {
1441.
            for ( ; i<ien ; i++ ) {
1442.
                if ( a[i] ) {
1443.
                    out.push( a[i][ prop ] );
1444.
                }
1445.
            }
1446.
        }
1447.
    
1448.
        return out;
1449.
    };
1450.
    
1451.
    
1452.
    // Basically the same as _pluck, but rather than looping over `a` we use `order`
1453.
    // as the indexes to pick from `a`
1454.
    var _pluck_order = function ( a, order, prop, prop2 )
1455.
    {
1456.
        var out = [];
1457.
        var i=0, ien=order.length;
1458.
    
1459.
        // Could have the test in the loop for slightly smaller code, but speed
1460.
        // is essential here
1461.
        if ( prop2 !== undefined ) {
1462.
            for ( ; i<ien ; i++ ) {
1463.
                if ( a[ order[i] ][ prop ] ) {
1464.
                    out.push( a[ order[i] ][ prop ][ prop2 ] );
1465.
                }
1466.
            }
1467.
        }
1468.
        else {
1469.
            for ( ; i<ien ; i++ ) {
1470.
                out.push( a[ order[i] ][ prop ] );
1471.
            }
1472.
        }
1473.
    
1474.
        return out;
1475.
    };
1476.
    
1477.
    
1478.
    var _range = function ( len, start )
1479.
    {
1480.
        var out = [];
1481.
        var end;
1482.
    
1483.
        if ( start === undefined ) {
1484.
            start = 0;
1485.
            end = len;
1486.
        }
1487.
        else {
1488.
            end = start;
1489.
            start = len;
1490.
        }
1491.
    
1492.
        for ( var i=start ; i<end ; i++ ) {
1493.
            out.push( i );
1494.
        }
1495.
    
1496.
        return out;
1497.
    };
1498.
    
1499.
    
1500.
    var _removeEmpty = function ( a )
1501.
    {
1502.
        var out = [];
1503.
    
1504.
        for ( var i=0, ien=a.length ; i<ien ; i++ ) {
1505.
            if ( a[i] ) { // careful - will remove all falsy values!
1506.
                out.push( a[i] );
1507.
            }
1508.
        }
1509.
    
1510.
        return out;
1511.
    };
1512.
    
1513.
    
1514.
    var _stripHtml = function ( d ) {
1515.
        return d.replace( _re_html, '' );
1516.
    };
1517.
    
1518.
    
1519.
    /**
1520.
     * Determine if all values in the array are unique. This means we can short
1521.
     * cut the _unique method at the cost of a single loop. A sorted array is used
1522.
     * to easily check the values.
1523.
     *
1524.
     * @param  {array} src Source array
1525.
     * @return {boolean} true if all unique, false otherwise
1526.
     * @ignore
1527.
     */
1528.
    var _areAllUnique = function ( src ) {
1529.
        if ( src.length < 2 ) {
1530.
            return true;
1531.
        }
1532.
    
1533.
        var sorted = src.slice().sort();
1534.
        var last = sorted[0];
1535.
    
1536.
        for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
1537.
            if ( sorted[i] === last ) {
1538.
                return false;
1539.
            }
1540.
    
1541.
            last = sorted[i];
1542.
        }
1543.
    
1544.
        return true;
1545.
    };
1546.
    
1547.
    
1548.
    /**
1549.
     * Find the unique elements in a source array.
1550.
     *
1551.
     * @param  {array} src Source array
1552.
     * @return {array} Array of unique items
1553.
     * @ignore
1554.
     */
1555.
    var _unique = function ( src )
1556.
    {
1557.
        if ( _areAllUnique( src ) ) {
1558.
            return src.slice();
1559.
        }
1560.
    
1561.
        // A faster unique method is to use object keys to identify used values,
1562.
        // but this doesn't work with arrays or objects, which we must also
1563.
        // consider. See jsperf.com/compare-array-unique-versions/4 for more
1564.
        // information.
1565.
        var
1566.
            out = [],
1567.
            val,
1568.
            i, ien=src.length,
1569.
            j, k=0;
1570.
    
1571.
        again: for ( i=0 ; i<ien ; i++ ) {
1572.
            val = src[i];
1573.
    
1574.
            for ( j=0 ; j<k ; j++ ) {
1575.
                if ( out[j] === val ) {
1576.
                    continue again;
1577.
                }
1578.
            }
1579.
    
1580.
            out.push( val );
1581.
            k++;
1582.
        }
1583.
    
1584.
        return out;
1585.
    };
1586.
    
1587.
    
1588.
    /**
1589.
     * DataTables utility methods
1590.
     * 
1591.
     * This namespace provides helper methods that DataTables uses internally to
1592.
     * create a DataTable, but which are not exclusively used only for DataTables.
1593.
     * These methods can be used by extension authors to save the duplication of
1594.
     * code.
1595.
     *
1596.
     *  @namespace
1597.
     */
1598.
    DataTable.util = {
1599.
        /**
1600.
         * Throttle the calls to a function. Arguments and context are maintained
1601.
         * for the throttled function.
1602.
         *
1603.
         * @param {function} fn Function to be called
1604.
         * @param {integer} freq Call frequency in mS
1605.
         * @return {function} Wrapped function
1606.
         */
1607.
        throttle: function ( fn, freq ) {
1608.
            var
1609.
                frequency = freq !== undefined ? freq : 200,
1610.
                last,
1611.
                timer;
1612.
    
1613.
            return function () {
1614.
                var
1615.
                    that = this,
1616.
                    now  = +new Date(),
1617.
                    args = arguments;
1618.
    
1619.
                if ( last && now < last + frequency ) {
1620.
                    clearTimeout( timer );
1621.
    
1622.
                    timer = setTimeout( function () {
1623.
                        last = undefined;
1624.
                        fn.apply( that, args );
1625.
                    }, frequency );
1626.
                }
1627.
                else {
1628.
                    last = now;
1629.
                    fn.apply( that, args );
1630.
                }
1631.
            };
1632.
        },
1633.
    
1634.
    
1635.
        /**
1636.
         * Escape a string such that it can be used in a regular expression
1637.
         *
1638.
         *  @param {string} val string to escape
1639.
         *  @returns {string} escaped string
1640.
         */
1641.
        escapeRegex: function ( val ) {
1642.
            return val.replace( _re_escape_regex, '\\$1' );
1643.
        }
1644.
    };
1645.
    
1646.
    
1647.
    
1648.
    /**
1649.
     * Create a mapping object that allows camel case parameters to be looked up
1650.
     * for their Hungarian counterparts. The mapping is stored in a private
1651.
     * parameter called `_hungarianMap` which can be accessed on the source object.
1652.
     *  @param {object} o
1653.
     *  @memberof DataTable#oApi
1654.
     */
1655.
    function _fnHungarianMap ( o )
1656.
    {
1657.
        var
1658.
            hungarian = 'a aa ai ao as b fn i m o s ',
1659.
            match,
1660.
            newKey,
1661.
            map = {};
1662.
    
1663.
        $.each( o, function (key, val) {
1664.
            match = key.match(/^([^A-Z]+?)([A-Z])/);
1665.
    
1666.
            if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
1667.
            {
1668.
                newKey = key.replace( match[0], match[2].toLowerCase() );
1669.
                map[ newKey ] = key;
1670.
    
1671.
                if ( match[1] === 'o' )
1672.
                {
1673.
                    _fnHungarianMap( o[key] );
1674.
                }
1675.
            }
1676.
        } );
1677.
    
1678.
        o._hungarianMap = map;
1679.
    }
1680.
    
1681.
    
1682.
    /**
1683.
     * Convert from camel case parameters to Hungarian, based on a Hungarian map
1684.
     * created by _fnHungarianMap.
1685.
     *  @param {object} src The model object which holds all parameters that can be
1686.
     *    mapped.
1687.
     *  @param {object} user The object to convert from camel case to Hungarian.
1688.
     *  @param {boolean} force When set to `true`, properties which already have a
1689.
     *    Hungarian value in the `user` object will be overwritten. Otherwise they
1690.
     *    won't be.
1691.
     *  @memberof DataTable#oApi
1692.
     */
1693.
    function _fnCamelToHungarian ( src, user, force )
1694.
    {
1695.
        if ( ! src._hungarianMap ) {
1696.
            _fnHungarianMap( src );
1697.
        }
1698.
    
1699.
        var hungarianKey;
1700.
    
1701.
        $.each( user, function (key, val) {
1702.
            hungarianKey = src._hungarianMap[ key ];
1703.
    
1704.
            if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
1705.
            {
1706.
                // For objects, we need to buzz down into the object to copy parameters
1707.
                if ( hungarianKey.charAt(0) === 'o' )
1708.
                {
1709.
                    // Copy the camelCase options over to the hungarian
1710.
                    if ( ! user[ hungarianKey ] ) {
1711.
                        user[ hungarianKey ] = {};
1712.
                    }
1713.
                    $.extend( true, user[hungarianKey], user[key] );
1714.
    
1715.
                    _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
1716.
                }
1717.
                else {
1718.
                    user[hungarianKey] = user[ key ];
1719.
                }
1720.
            }
1721.
        } );
1722.
    }
1723.
    
1724.
    
1725.
    /**
1726.
     * Language compatibility - when certain options are given, and others aren't, we
1727.
     * need to duplicate the values over, in order to provide backwards compatibility
1728.
     * with older language files.
1729.
     *  @param {object} oSettings dataTables settings object
1730.
     *  @memberof DataTable#oApi
1731.
     */
1732.
    function _fnLanguageCompat( lang )
1733.
    {
1734.
        // Note the use of the Hungarian notation for the parameters in this method as
1735.
        // this is called after the mapping of camelCase to Hungarian
1736.
        var defaults = DataTable.defaults.oLanguage;
1737.
    
1738.
        // Default mapping
1739.
        var defaultDecimal = defaults.sDecimal;
1740.
        if ( defaultDecimal ) {
1741.
            _addNumericSort( defaultDecimal );
1742.
        }
1743.
    
1744.
        if ( lang ) {
1745.
            var zeroRecords = lang.sZeroRecords;
1746.
    
1747.
            // Backwards compatibility - if there is no sEmptyTable given, then use the same as
1748.
            // sZeroRecords - assuming that is given.
1749.
            if ( ! lang.sEmptyTable && zeroRecords &&
1750.
                defaults.sEmptyTable === "No data available in table" )
1751.
            {
1752.
                _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
1753.
            }
1754.
    
1755.
            // Likewise with loading records
1756.
            if ( ! lang.sLoadingRecords && zeroRecords &&
1757.
                defaults.sLoadingRecords === "Loading..." )
1758.
            {
1759.
                _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
1760.
            }
1761.
    
1762.
            // Old parameter name of the thousands separator mapped onto the new
1763.
            if ( lang.sInfoThousands ) {
1764.
                lang.sThousands = lang.sInfoThousands;
1765.
            }
1766.
    
1767.
            var decimal = lang.sDecimal;
1768.
            if ( decimal && defaultDecimal !== decimal ) {
1769.
                _addNumericSort( decimal );
1770.
            }
1771.
        }
1772.
    }
1773.
    
1774.
    
1775.
    /**
1776.
     * Map one parameter onto another
1777.
     *  @param {object} o Object to map
1778.
     *  @param {*} knew The new parameter name
1779.
     *  @param {*} old The old parameter name
1780.
     */
1781.
    var _fnCompatMap = function ( o, knew, old ) {
1782.
        if ( o[ knew ] !== undefined ) {
1783.
            o[ old ] = o[ knew ];
1784.
        }
1785.
    };
1786.
    
1787.
    
1788.
    /**
1789.
     * Provide backwards compatibility for the main DT options. Note that the new
1790.
     * options are mapped onto the old parameters, so this is an external interface
1791.
     * change only.
1792.
     *  @param {object} init Object to map
1793.
     */
1794.
    function _fnCompatOpts ( init )
1795.
    {
1796.
        _fnCompatMap( init, 'ordering',      'bSort' );
1797.
        _fnCompatMap( init, 'orderMulti',    'bSortMulti' );
1798.
        _fnCompatMap( init, 'orderClasses',  'bSortClasses' );
1799.
        _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
1800.
        _fnCompatMap( init, 'order',         'aaSorting' );
1801.
        _fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
1802.
        _fnCompatMap( init, 'paging',        'bPaginate' );
1803.
        _fnCompatMap( init, 'pagingType',    'sPaginationType' );
1804.
        _fnCompatMap( init, 'pageLength',    'iDisplayLength' );
1805.
        _fnCompatMap( init, 'searching',     'bFilter' );
1806.
    
1807.
        // Boolean initialisation of x-scrolling
1808.
        if ( typeof init.sScrollX === 'boolean' ) {
1809.
            init.sScrollX = init.sScrollX ? '100%' : '';
1810.
        }
1811.
        if ( typeof init.scrollX === 'boolean' ) {
1812.
            init.scrollX = init.scrollX ? '100%' : '';
1813.
        }
1814.
    
1815.
        // Column search objects are in an array, so it needs to be converted
1816.
        // element by element
1817.
        var searchCols = init.aoSearchCols;
1818.
    
1819.
        if ( searchCols ) {
1820.
            for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
1821.
                if ( searchCols[i] ) {
1822.
                    _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
1823.
                }
1824.
            }
1825.
        }
1826.
    }
1827.
    
1828.
    
1829.
    /**
1830.
     * Provide backwards compatibility for column options. Note that the new options
1831.
     * are mapped onto the old parameters, so this is an external interface change
1832.
     * only.
1833.
     *  @param {object} init Object to map
1834.
     */
1835.
    function _fnCompatCols ( init )
1836.
    {
1837.
        _fnCompatMap( init, 'orderable',     'bSortable' );
1838.
        _fnCompatMap( init, 'orderData',     'aDataSort' );
1839.
        _fnCompatMap( init, 'orderSequence', 'asSorting' );
1840.
        _fnCompatMap( init, 'orderDataType', 'sortDataType' );
1841.
    
1842.
        // orderData can be given as an integer
1843.
        var dataSort = init.aDataSort;
1844.
        if ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {
1845.
            init.aDataSort = [ dataSort ];
1846.
        }
1847.
    }
1848.
    
1849.
    
1850.
    /**
1851.
     * Browser feature detection for capabilities, quirks
1852.
     *  @param {object} settings dataTables settings object
1853.
     *  @memberof DataTable#oApi
1854.
     */
1855.
    function _fnBrowserDetect( settings )
1856.
    {
1857.
        // We don't need to do this every time DataTables is constructed, the values
1858.
        // calculated are specific to the browser and OS configuration which we
1859.
        // don't expect to change between initialisations
1860.
        if ( ! DataTable.__browser ) {
1861.
            var browser = {};
1862.
            DataTable.__browser = browser;
1863.
    
1864.
            // Scrolling feature / quirks detection
1865.
            var n = $('<div/>')
1866.
                .css( {
1867.
                    position: 'fixed',
1868.
                    top: 0,
1869.
                    left: $(window).scrollLeft()*-1, // allow for scrolling
1870.
                    height: 1,
1871.
                    width: 1,
1872.
                    overflow: 'hidden'
1873.
                } )
1874.
                .append(
1875.
                    $('<div/>')
1876.
                        .css( {
1877.
                            position: 'absolute',
1878.
                            top: 1,
1879.
                            left: 1,
1880.
                            width: 100,
1881.
                            overflow: 'scroll'
1882.
                        } )
1883.
                        .append(
1884.
                            $('<div/>')
1885.
                                .css( {
1886.
                                    width: '100%',
1887.
                                    height: 10
1888.
                                } )
1889.
                        )
1890.
                )
1891.
                .appendTo( 'body' );
1892.
    
1893.
            var outer = n.children();
1894.
            var inner = outer.children();
1895.
    
1896.
            // Numbers below, in order, are:
1897.
            // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
1898.
            //
1899.
            // IE6 XP:                           100 100 100  83
1900.
            // IE7 Vista:                        100 100 100  83
1901.
            // IE 8+ Windows:                     83  83 100  83
1902.
            // Evergreen Windows:                 83  83 100  83
1903.
            // Evergreen Mac with scrollbars:     85  85 100  85
1904.
            // Evergreen Mac without scrollbars: 100 100 100 100
1905.
    
1906.
            // Get scrollbar width
1907.
            browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
1908.
    
1909.
            // IE6/7 will oversize a width 100% element inside a scrolling element, to
1910.
            // include the width of the scrollbar, while other browsers ensure the inner
1911.
            // element is contained without forcing scrolling
1912.
            browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
1913.
    
1914.
            // In rtl text layout, some browsers (most, but not all) will place the
1915.
            // scrollbar on the left, rather than the right.
1916.
            browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
1917.
    
1918.
            // IE8- don't provide height and width for getBoundingClientRect
1919.
            browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
1920.
    
1921.
            n.remove();
1922.
        }
1923.
    
1924.
        $.extend( settings.oBrowser, DataTable.__browser );
1925.
        settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
1926.
    }
1927.
    
1928.
    
1929.
    /**
1930.
     * Array.prototype reduce[Right] method, used for browsers which don't support
1931.
     * JS 1.6. Done this way to reduce code size, since we iterate either way
1932.
     *  @param {object} settings dataTables settings object
1933.
     *  @memberof DataTable#oApi
1934.
     */
1935.
    function _fnReduce ( that, fn, init, start, end, inc )
1936.
    {
1937.
        var
1938.
            i = start,
1939.
            value,
1940.
            isSet = false;
1941.
    
1942.
        if ( init !== undefined ) {
1943.
            value = init;
1944.
            isSet = true;
1945.
        }
1946.
    
1947.
        while ( i !== end ) {
1948.
            if ( ! that.hasOwnProperty(i) ) {
1949.
                continue;
1950.
            }
1951.
    
1952.
            value = isSet ?
1953.
                fn( value, that[i], i, that ) :
1954.
                that[i];
1955.
    
1956.
            isSet = true;
1957.
            i += inc;
1958.
        }
1959.
    
1960.
        return value;
1961.
    }
1962.
    
1963.
    /**
1964.
     * Add a column to the list used for the table with default values
1965.
     *  @param {object} oSettings dataTables settings object
1966.
     *  @param {node} nTh The th element for this column
1967.
     *  @memberof DataTable#oApi
1968.
     */
1969.
    function _fnAddColumn( oSettings, nTh )
1970.
    {
1971.
        // Add column to aoColumns array
1972.
        var oDefaults = DataTable.defaults.column;
1973.
        var iCol = oSettings.aoColumns.length;
1974.
        var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
1975.
            "nTh": nTh ? nTh : document.createElement('th'),
1976.
            "sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
1977.
            "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
1978.
            "mData": oDefaults.mData ? oDefaults.mData : iCol,
1979.
            idx: iCol
1980.
        } );
1981.
        oSettings.aoColumns.push( oCol );
1982.
    
1983.
        // Add search object for column specific search. Note that the `searchCols[ iCol ]`
1984.
        // passed into extend can be undefined. This allows the user to give a default
1985.
        // with only some of the parameters defined, and also not give a default
1986.
        var searchCols = oSettings.aoPreSearchCols;
1987.
        searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
1988.
    
1989.
        // Use the default column options function to initialise classes etc
1990.
        _fnColumnOptions( oSettings, iCol, $(nTh).data() );
1991.
    }
1992.
    
1993.
    
1994.
    /**
1995.
     * Apply options for a column
1996.
     *  @param {object} oSettings dataTables settings object
1997.
     *  @param {int} iCol column index to consider
1998.
     *  @param {object} oOptions object with sType, bVisible and bSearchable etc
1999.
     *  @memberof DataTable#oApi
2000.
     */
2001.
    function _fnColumnOptions( oSettings, iCol, oOptions )
2002.
    {
2003.
        var oCol = oSettings.aoColumns[ iCol ];
2004.
        var oClasses = oSettings.oClasses;
2005.
        var th = $(oCol.nTh);
2006.
    
2007.
        // Try to get width information from the DOM. We can't get it from CSS
2008.
        // as we'd need to parse the CSS stylesheet. `width` option can override
2009.
        if ( ! oCol.sWidthOrig ) {
2010.
            // Width attribute
2011.
            oCol.sWidthOrig = th.attr('width') || null;
2012.
    
2013.
            // Style attribute
2014.
            var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
2015.
            if ( t ) {
2016.
                oCol.sWidthOrig = t[1];
2017.
            }
2018.
        }
2019.
    
2020.
        /* User specified column options */
2021.
        if ( oOptions !== undefined && oOptions !== null )
2022.
        {
2023.
            // Backwards compatibility
2024.
            _fnCompatCols( oOptions );
2025.
    
2026.
            // Map camel case parameters to their Hungarian counterparts
2027.
            _fnCamelToHungarian( DataTable.defaults.column, oOptions, true );
2028.
    
2029.
            /* Backwards compatibility for mDataProp */
2030.
            if ( oOptions.mDataProp !== undefined && !oOptions.mData )
2031.
            {
2032.
                oOptions.mData = oOptions.mDataProp;
2033.
            }
2034.
    
2035.
            if ( oOptions.sType )
2036.
            {
2037.
                oCol._sManualType = oOptions.sType;
2038.
            }
2039.
    
2040.
            // `class` is a reserved word in Javascript, so we need to provide
2041.
            // the ability to use a valid name for the camel case input
2042.
            if ( oOptions.className && ! oOptions.sClass )
2043.
            {
2044.
                oOptions.sClass = oOptions.className;
2045.
            }
2046.
            if ( oOptions.sClass ) {
2047.
                th.addClass( oOptions.sClass );
2048.
            }
2049.
    
2050.
            $.extend( oCol, oOptions );
2051.
            _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
2052.
    
2053.
            /* iDataSort to be applied (backwards compatibility), but aDataSort will take
2054.
             * priority if defined
2055.
             */
2056.
            if ( oOptions.iDataSort !== undefined )
2057.
            {
2058.
                oCol.aDataSort = [ oOptions.iDataSort ];
2059.
            }
2060.
            _fnMap( oCol, oOptions, "aDataSort" );
2061.
        }
2062.
    
2063.
        /* Cache the data get and set functions for speed */
2064.
        var mDataSrc = oCol.mData;
2065.
        var mData = _fnGetObjectDataFn( mDataSrc );
2066.
        var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
2067.
    
2068.
        var attrTest = function( src ) {
2069.
            return typeof src === 'string' && src.indexOf('@') !== -1;
2070.
        };
2071.
        oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
2072.
            attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
2073.
        );
2074.
        oCol._setter = null;
2075.
    
2076.
        oCol.fnGetData = function (rowData, type, meta) {
2077.
            var innerData = mData( rowData, type, undefined, meta );
2078.
    
2079.
            return mRender && type ?
2080.
                mRender( innerData, type, rowData, meta ) :
2081.
                innerData;
2082.
        };
2083.
        oCol.fnSetData = function ( rowData, val, meta ) {
2084.
            return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
2085.
        };
2086.
    
2087.
        // Indicate if DataTables should read DOM data as an object or array
2088.
        // Used in _fnGetRowElements
2089.
        if ( typeof mDataSrc !== 'number' ) {
2090.
            oSettings._rowReadObject = true;
2091.
        }
2092.
    
2093.
        /* Feature sorting overrides column specific when off */
2094.
        if ( !oSettings.oFeatures.bSort )
2095.
        {
2096.
            oCol.bSortable = false;
2097.
            th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
2098.
        }
2099.
    
2100.
        /* Check that the class assignment is correct for sorting */
2101.
        var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
2102.
        var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
2103.
        if ( !oCol.bSortable || (!bAsc && !bDesc) )
2104.
        {
2105.
            oCol.sSortingClass = oClasses.sSortableNone;
2106.
            oCol.sSortingClassJUI = "";
2107.
        }
2108.
        else if ( bAsc && !bDesc )
2109.
        {
2110.
            oCol.sSortingClass = oClasses.sSortableAsc;
2111.
            oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
2112.
        }
2113.
        else if ( !bAsc && bDesc )
2114.
        {
2115.
            oCol.sSortingClass = oClasses.sSortableDesc;
2116.
            oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
2117.
        }
2118.
        else
2119.
        {
2120.
            oCol.sSortingClass = oClasses.sSortable;
2121.
            oCol.sSortingClassJUI = oClasses.sSortJUI;
2122.
        }
2123.
    }
2124.
    
2125.
    
2126.
    /**
2127.
     * Adjust the table column widths for new data. Note: you would probably want to
2128.
     * do a redraw after calling this function!
2129.
     *  @param {object} settings dataTables settings object
2130.
     *  @memberof DataTable#oApi
2131.
     */
2132.
    function _fnAdjustColumnSizing ( settings )
2133.
    {
2134.
        /* Not interested in doing column width calculation if auto-width is disabled */
2135.
        if ( settings.oFeatures.bAutoWidth !== false )
2136.
        {
2137.
            var columns = settings.aoColumns;
2138.
    
2139.
            _fnCalculateColumnWidths( settings );
2140.
            for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
2141.
            {
2142.
                columns[i].nTh.style.width = columns[i].sWidth;
2143.
            }
2144.
        }
2145.
    
2146.
        var scroll = settings.oScroll;
2147.
        if ( scroll.sY !== '' || scroll.sX !== '')
2148.
        {
2149.
            _fnScrollDraw( settings );
2150.
        }
2151.
    
2152.
        _fnCallbackFire( settings, null, 'column-sizing', [settings] );
2153.
    }
2154.
    
2155.
    
2156.
    /**
2157.
     * Covert the index of a visible column to the index in the data array (take account
2158.
     * of hidden columns)
2159.
     *  @param {object} oSettings dataTables settings object
2160.
     *  @param {int} iMatch Visible column index to lookup
2161.
     *  @returns {int} i the data index
2162.
     *  @memberof DataTable#oApi
2163.
     */
2164.
    function _fnVisibleToColumnIndex( oSettings, iMatch )
2165.
    {
2166.
        var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2167.
    
2168.
        return typeof aiVis[iMatch] === 'number' ?
2169.
            aiVis[iMatch] :
2170.
            null;
2171.
    }
2172.
    
2173.
    
2174.
    /**
2175.
     * Covert the index of an index in the data array and convert it to the visible
2176.
     *   column index (take account of hidden columns)
2177.
     *  @param {int} iMatch Column index to lookup
2178.
     *  @param {object} oSettings dataTables settings object
2179.
     *  @returns {int} i the data index
2180.
     *  @memberof DataTable#oApi
2181.
     */
2182.
    function _fnColumnIndexToVisible( oSettings, iMatch )
2183.
    {
2184.
        var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2185.
        var iPos = $.inArray( iMatch, aiVis );
2186.
    
2187.
        return iPos !== -1 ? iPos : null;
2188.
    }
2189.
    
2190.
    
2191.
    /**
2192.
     * Get the number of visible columns
2193.
     *  @param {object} oSettings dataTables settings object
2194.
     *  @returns {int} i the number of visible columns
2195.
     *  @memberof DataTable#oApi
2196.
     */
2197.
    function _fnVisbleColumns( oSettings )
2198.
    {
2199.
        var vis = 0;
2200.
    
2201.
        // No reduce in IE8, use a loop for now
2202.
        $.each( oSettings.aoColumns, function ( i, col ) {
2203.
            if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
2204.
                vis++;
2205.
            }
2206.
        } );
2207.
    
2208.
        return vis;
2209.
    }
2210.
    
2211.
    
2212.
    /**
2213.
     * Get an array of column indexes that match a given property
2214.
     *  @param {object} oSettings dataTables settings object
2215.
     *  @param {string} sParam Parameter in aoColumns to look for - typically
2216.
     *    bVisible or bSearchable
2217.
     *  @returns {array} Array of indexes with matched properties
2218.
     *  @memberof DataTable#oApi
2219.
     */
2220.
    function _fnGetColumns( oSettings, sParam )
2221.
    {
2222.
        var a = [];
2223.
    
2224.
        $.map( oSettings.aoColumns, function(val, i) {
2225.
            if ( val[sParam] ) {
2226.
                a.push( i );
2227.
            }
2228.
        } );
2229.
    
2230.
        return a;
2231.
    }
2232.
    
2233.
    
2234.
    /**
2235.
     * Calculate the 'type' of a column
2236.
     *  @param {object} settings dataTables settings object
2237.
     *  @memberof DataTable#oApi
2238.
     */
2239.
    function _fnColumnTypes ( settings )
2240.
    {
2241.
        var columns = settings.aoColumns;
2242.
        var data = settings.aoData;
2243.
        var types = DataTable.ext.type.detect;
2244.
        var i, ien, j, jen, k, ken;
2245.
        var col, cell, detectedType, cache;
2246.
    
2247.
        // For each column, spin over the 
2248.
        for ( i=0, ien=columns.length ; i<ien ; i++ ) {
2249.
            col = columns[i];
2250.
            cache = [];
2251.
    
2252.
            if ( ! col.sType && col._sManualType ) {
2253.
                col.sType = col._sManualType;
2254.
            }
2255.
            else if ( ! col.sType ) {
2256.
                for ( j=0, jen=types.length ; j<jen ; j++ ) {
2257.
                    for ( k=0, ken=data.length ; k<ken ; k++ ) {
2258.
                        // Use a cache array so we only need to get the type data
2259.
                        // from the formatter once (when using multiple detectors)
2260.
                        if ( cache[k] === undefined ) {
2261.
                            cache[k] = _fnGetCellData( settings, k, i, 'type' );
2262.
                        }
2263.
    
2264.
                        detectedType = types[j]( cache[k], settings );
2265.
    
2266.
                        // If null, then this type can't apply to this column, so
2267.
                        // rather than testing all cells, break out. There is an
2268.
                        // exception for the last type which is `html`. We need to
2269.
                        // scan all rows since it is possible to mix string and HTML
2270.
                        // types
2271.
                        if ( ! detectedType && j !== types.length-1 ) {
2272.
                            break;
2273.
                        }
2274.
    
2275.
                        // Only a single match is needed for html type since it is
2276.
                        // bottom of the pile and very similar to string
2277.
                        if ( detectedType === 'html' ) {
2278.
                            break;
2279.
                        }
2280.
                    }
2281.
    
2282.
                    // Type is valid for all data points in the column - use this
2283.
                    // type
2284.
                    if ( detectedType ) {
2285.
                        col.sType = detectedType;
2286.
                        break;
2287.
                    }
2288.
                }
2289.
    
2290.
                // Fall back - if no type was detected, always use string
2291.
                if ( ! col.sType ) {
2292.
                    col.sType = 'string';
2293.
                }
2294.
            }
2295.
        }
2296.
    }
2297.
    
2298.
    
2299.
    /**
2300.
     * Take the column definitions and static columns arrays and calculate how
2301.
     * they relate to column indexes. The callback function will then apply the
2302.
     * definition found for a column to a suitable configuration object.
2303.
     *  @param {object} oSettings dataTables settings object
2304.
     *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
2305.
     *  @param {array} aoCols The aoColumns array that defines columns individually
2306.
     *  @param {function} fn Callback function - takes two parameters, the calculated
2307.
     *    column index and the definition for that column.
2308.
     *  @memberof DataTable#oApi
2309.
     */
2310.
    function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
2311.
    {
2312.
        var i, iLen, j, jLen, k, kLen, def;
2313.
        var columns = oSettings.aoColumns;
2314.
    
2315.
        // Column definitions with aTargets
2316.
        if ( aoColDefs )
2317.
        {
2318.
            /* Loop over the definitions array - loop in reverse so first instance has priority */
2319.
            for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
2320.
            {
2321.
                def = aoColDefs[i];
2322.
    
2323.
                /* Each definition can target multiple columns, as it is an array */
2324.
                var aTargets = def.targets !== undefined ?
2325.
                    def.targets :
2326.
                    def.aTargets;
2327.
    
2328.
                if ( ! $.isArray( aTargets ) )
2329.
                {
2330.
                    aTargets = [ aTargets ];
2331.
                }
2332.
    
2333.
                for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
2334.
                {
2335.
                    if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
2336.
                    {
2337.
                        /* Add columns that we don't yet know about */
2338.
                        while( columns.length <= aTargets[j] )
2339.
                        {
2340.
                            _fnAddColumn( oSettings );
2341.
                        }
2342.
    
2343.
                        /* Integer, basic index */
2344.
                        fn( aTargets[j], def );
2345.
                    }
2346.
                    else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
2347.
                    {
2348.
                        /* Negative integer, right to left column counting */
2349.
                        fn( columns.length+aTargets[j], def );
2350.
                    }
2351.
                    else if ( typeof aTargets[j] === 'string' )
2352.
                    {
2353.
                        /* Class name matching on TH element */
2354.
                        for ( k=0, kLen=columns.length ; k<kLen ; k++ )
2355.
                        {
2356.
                            if ( aTargets[j] == "_all" ||
2357.
                                 $(columns[k].nTh).hasClass( aTargets[j] ) )
2358.
                            {
2359.
                                fn( k, def );
2360.
                            }
2361.
                        }
2362.
                    }
2363.
                }
2364.
            }
2365.
        }
2366.
    
2367.
        // Statically defined columns array
2368.
        if ( aoCols )
2369.
        {
2370.
            for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
2371.
            {
2372.
                fn( i, aoCols[i] );
2373.
            }
2374.
        }
2375.
    }
2376.
    
2377.
    /**
2378.
     * Add a data array to the table, creating DOM node etc. This is the parallel to
2379.
     * _fnGatherData, but for adding rows from a Javascript source, rather than a
2380.
     * DOM source.
2381.
     *  @param {object} oSettings dataTables settings object
2382.
     *  @param {array} aData data array to be added
2383.
     *  @param {node} [nTr] TR element to add to the table - optional. If not given,
2384.
     *    DataTables will create a row automatically
2385.
     *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
2386.
     *    if nTr is.
2387.
     *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
2388.
     *  @memberof DataTable#oApi
2389.
     */
2390.
    function _fnAddData ( oSettings, aDataIn, nTr, anTds )
2391.
    {
2392.
        /* Create the object for storing information about this new row */
2393.
        var iRow = oSettings.aoData.length;
2394.
        var oData = $.extend( true, {}, DataTable.models.oRow, {
2395.
            src: nTr ? 'dom' : 'data',
2396.
            idx: iRow
2397.
        } );
2398.
    
2399.
        oData._aData = aDataIn;
2400.
        oSettings.aoData.push( oData );
2401.
    
2402.
        /* Create the cells */
2403.
        var nTd, sThisType;
2404.
        var columns = oSettings.aoColumns;
2405.
    
2406.
        // Invalidate the column types as the new data needs to be revalidated
2407.
        for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
2408.
        {
2409.
            columns[i].sType = null;
2410.
        }
2411.
    
2412.
        /* Add to the display array */
2413.
        oSettings.aiDisplayMaster.push( iRow );
2414.
    
2415.
        var id = oSettings.rowIdFn( aDataIn );
2416.
        if ( id !== undefined ) {
2417.
            oSettings.aIds[ id ] = oData;
2418.
        }
2419.
    
2420.
        /* Create the DOM information, or register it if already present */
2421.
        if ( nTr || ! oSettings.oFeatures.bDeferRender )
2422.
        {
2423.
            _fnCreateTr( oSettings, iRow, nTr, anTds );
2424.
        }
2425.
    
2426.
        return iRow;
2427.
    }
2428.
    
2429.
    
2430.
    /**
2431.
     * Add one or more TR elements to the table. Generally we'd expect to
2432.
     * use this for reading data from a DOM sourced table, but it could be
2433.
     * used for an TR element. Note that if a TR is given, it is used (i.e.
2434.
     * it is not cloned).
2435.
     *  @param {object} settings dataTables settings object
2436.
     *  @param {array|node|jQuery} trs The TR element(s) to add to the table
2437.
     *  @returns {array} Array of indexes for the added rows
2438.
     *  @memberof DataTable#oApi
2439.
     */
2440.
    function _fnAddTr( settings, trs )
2441.
    {
2442.
        var row;
2443.
    
2444.
        // Allow an individual node to be passed in
2445.
        if ( ! (trs instanceof $) ) {
2446.
            trs = $(trs);
2447.
        }
2448.
    
2449.
        return trs.map( function (i, el) {
2450.
            row = _fnGetRowElements( settings, el );
2451.
            return _fnAddData( settings, row.data, el, row.cells );
2452.
        } );
2453.
    }
2454.
    
2455.
    
2456.
    /**
2457.
     * Take a TR element and convert it to an index in aoData
2458.
     *  @param {object} oSettings dataTables settings object
2459.
     *  @param {node} n the TR element to find
2460.
     *  @returns {int} index if the node is found, null if not
2461.
     *  @memberof DataTable#oApi
2462.
     */
2463.
    function _fnNodeToDataIndex( oSettings, n )
2464.
    {
2465.
        return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
2466.
    }
2467.
    
2468.
    
2469.
    /**
2470.
     * Take a TD element and convert it into a column data index (not the visible index)
2471.
     *  @param {object} oSettings dataTables settings object
2472.
     *  @param {int} iRow The row number the TD/TH can be found in
2473.
     *  @param {node} n The TD/TH element to find
2474.
     *  @returns {int} index if the node is found, -1 if not
2475.
     *  @memberof DataTable#oApi
2476.
     */
2477.
    function _fnNodeToColumnIndex( oSettings, iRow, n )
2478.
    {
2479.
        return $.inArray( n, oSettings.aoData[ iRow ].anCells );
2480.
    }
2481.
    
2482.
    
2483.
    /**
2484.
     * Get the data for a given cell from the internal cache, taking into account data mapping
2485.
     *  @param {object} settings dataTables settings object
2486.
     *  @param {int} rowIdx aoData row id
2487.
     *  @param {int} colIdx Column index
2488.
     *  @param {string} type data get type ('display', 'type' 'filter' 'sort')
2489.
     *  @returns {*} Cell data
2490.
     *  @memberof DataTable#oApi
2491.
     */
2492.
    function _fnGetCellData( settings, rowIdx, colIdx, type )
2493.
    {
2494.
        var draw           = settings.iDraw;
2495.
        var col            = settings.aoColumns[colIdx];
2496.
        var rowData        = settings.aoData[rowIdx]._aData;
2497.
        var defaultContent = col.sDefaultContent;
2498.
        var cellData       = col.fnGetData( rowData, type, {
2499.
            settings: settings,
2500.
            row:      rowIdx,
2501.
            col:      colIdx
2502.
        } );
2503.
    
2504.
        if ( cellData === undefined ) {
2505.
            if ( settings.iDrawError != draw && defaultContent === null ) {
2506.
                _fnLog( settings, 0, "Requested unknown parameter "+
2507.
                    (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
2508.
                    " for row "+rowIdx+", column "+colIdx, 4 );
2509.
                settings.iDrawError = draw;
2510.
            }
2511.
            return defaultContent;
2512.
        }
2513.
    
2514.
        // When the data source is null and a specific data type is requested (i.e.
2515.
        // not the original data), we can use default column data
2516.
        if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
2517.
            cellData = defaultContent;
2518.
        }
2519.
        else if ( typeof cellData === 'function' ) {
2520.
            // If the data source is a function, then we run it and use the return,
2521.
            // executing in the scope of the data object (for instances)
2522.
            return cellData.call( rowData );
2523.
        }
2524.
    
2525.
        if ( cellData === null && type == 'display' ) {
2526.
            return '';
2527.
        }
2528.
        return cellData;
2529.
    }
2530.
    
2531.
    
2532.
    /**
2533.
     * Set the value for a specific cell, into the internal data cache
2534.
     *  @param {object} settings dataTables settings object
2535.
     *  @param {int} rowIdx aoData row id
2536.
     *  @param {int} colIdx Column index
2537.
     *  @param {*} val Value to set
2538.
     *  @memberof DataTable#oApi
2539.
     */
2540.
    function _fnSetCellData( settings, rowIdx, colIdx, val )
2541.
    {
2542.
        var col     = settings.aoColumns[colIdx];
2543.
        var rowData = settings.aoData[rowIdx]._aData;
2544.
    
2545.
        col.fnSetData( rowData, val, {
2546.
            settings: settings,
2547.
            row:      rowIdx,
2548.
            col:      colIdx
2549.
        }  );
2550.
    }
2551.
    
2552.
    
2553.
    // Private variable that is used to match action syntax in the data property object
2554.
    var __reArray = /\[.*?\]$/;
2555.
    var __reFn = /\(\)$/;
2556.
    
2557.
    /**
2558.
     * Split string on periods, taking into account escaped periods
2559.
     * @param  {string} str String to split
2560.
     * @return {array} Split string
2561.
     */
2562.
    function _fnSplitObjNotation( str )
2563.
    {
2564.
        return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
2565.
            return s.replace(/\\\./g, '.');
2566.
        } );
2567.
    }
2568.
    
2569.
    
2570.
    /**
2571.
     * Return a function that can be used to get data from a source object, taking
2572.
     * into account the ability to use nested objects as a source
2573.
     *  @param {string|int|function} mSource The data source for the object
2574.
     *  @returns {function} Data get function
2575.
     *  @memberof DataTable#oApi
2576.
     */
2577.
    function _fnGetObjectDataFn( mSource )
2578.
    {
2579.
        if ( $.isPlainObject( mSource ) )
2580.
        {
2581.
            /* Build an object of get functions, and wrap them in a single call */
2582.
            var o = {};
2583.
            $.each( mSource, function (key, val) {
2584.
                if ( val ) {
2585.
                    o[key] = _fnGetObjectDataFn( val );
2586.
                }
2587.
            } );
2588.
    
2589.
            return function (data, type, row, meta) {
2590.
                var t = o[type] || o._;
2591.
                return t !== undefined ?
2592.
                    t(data, type, row, meta) :
2593.
                    data;
2594.
            };
2595.
        }
2596.
        else if ( mSource === null )
2597.
        {
2598.
            /* Give an empty string for rendering / sorting etc */
2599.
            return function (data) { // type, row and meta also passed, but not used
2600.
                return data;
2601.
            };
2602.
        }
2603.
        else if ( typeof mSource === 'function' )
2604.
        {
2605.
            return function (data, type, row, meta) {
2606.
                return mSource( data, type, row, meta );
2607.
            };
2608.
        }
2609.
        else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2610.
                  mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2611.
        {
2612.
            /* If there is a . in the source string then the data source is in a
2613.
             * nested object so we loop over the data for each level to get the next
2614.
             * level down. On each loop we test for undefined, and if found immediately
2615.
             * return. This allows entire objects to be missing and sDefaultContent to
2616.
             * be used if defined, rather than throwing an error
2617.
             */
2618.
            var fetchData = function (data, type, src) {
2619.
                var arrayNotation, funcNotation, out, innerSrc;
2620.
    
2621.
                if ( src !== "" )
2622.
                {
2623.
                    var a = _fnSplitObjNotation( src );
2624.
    
2625.
                    for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2626.
                    {
2627.
                        // Check if we are dealing with special notation
2628.
                        arrayNotation = a[i].match(__reArray);
2629.
                        funcNotation = a[i].match(__reFn);
2630.
    
2631.
                        if ( arrayNotation )
2632.
                        {
2633.
                            // Array notation
2634.
                            a[i] = a[i].replace(__reArray, '');
2635.
    
2636.
                            // Condition allows simply [] to be passed in
2637.
                            if ( a[i] !== "" ) {
2638.
                                data = data[ a[i] ];
2639.
                            }
2640.
                            out = [];
2641.
    
2642.
                            // Get the remainder of the nested object to get
2643.
                            a.splice( 0, i+1 );
2644.
                            innerSrc = a.join('.');
2645.
    
2646.
                            // Traverse each entry in the array getting the properties requested
2647.
                            if ( $.isArray( data ) ) {
2648.
                                for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
2649.
                                    out.push( fetchData( data[j], type, innerSrc ) );
2650.
                                }
2651.
                            }
2652.
    
2653.
                            // If a string is given in between the array notation indicators, that
2654.
                            // is used to join the strings together, otherwise an array is returned
2655.
                            var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
2656.
                            data = (join==="") ? out : out.join(join);
2657.
    
2658.
                            // The inner call to fetchData has already traversed through the remainder
2659.
                            // of the source requested, so we exit from the loop
2660.
                            break;
2661.
                        }
2662.
                        else if ( funcNotation )
2663.
                        {
2664.
                            // Function call
2665.
                            a[i] = a[i].replace(__reFn, '');
2666.
                            data = data[ a[i] ]();
2667.
                            continue;
2668.
                        }
2669.
    
2670.
                        if ( data === null || data[ a[i] ] === undefined )
2671.
                        {
2672.
                            return undefined;
2673.
                        }
2674.
                        data = data[ a[i] ];
2675.
                    }
2676.
                }
2677.
    
2678.
                return data;
2679.
            };
2680.
    
2681.
            return function (data, type) { // row and meta also passed, but not used
2682.
                return fetchData( data, type, mSource );
2683.
            };
2684.
        }
2685.
        else
2686.
        {
2687.
            /* Array or flat object mapping */
2688.
            return function (data, type) { // row and meta also passed, but not used
2689.
                return data[mSource];
2690.
            };
2691.
        }
2692.
    }
2693.
    
2694.
    
2695.
    /**
2696.
     * Return a function that can be used to set data from a source object, taking
2697.
     * into account the ability to use nested objects as a source
2698.
     *  @param {string|int|function} mSource The data source for the object
2699.
     *  @returns {function} Data set function
2700.
     *  @memberof DataTable#oApi
2701.
     */
2702.
    function _fnSetObjectDataFn( mSource )
2703.
    {
2704.
        if ( $.isPlainObject( mSource ) )
2705.
        {
2706.
            /* Unlike get, only the underscore (global) option is used for for
2707.
             * setting data since we don't know the type here. This is why an object
2708.
             * option is not documented for `mData` (which is read/write), but it is
2709.
             * for `mRender` which is read only.
2710.
             */
2711.
            return _fnSetObjectDataFn( mSource._ );
2712.
        }
2713.
        else if ( mSource === null )
2714.
        {
2715.
            /* Nothing to do when the data source is null */
2716.
            return function () {};
2717.
        }
2718.
        else if ( typeof mSource === 'function' )
2719.
        {
2720.
            return function (data, val, meta) {
2721.
                mSource( data, 'set', val, meta );
2722.
            };
2723.
        }
2724.
        else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2725.
                  mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2726.
        {
2727.
            /* Like the get, we need to get data from a nested object */
2728.
            var setData = function (data, val, src) {
2729.
                var a = _fnSplitObjNotation( src ), b;
2730.
                var aLast = a[a.length-1];
2731.
                var arrayNotation, funcNotation, o, innerSrc;
2732.
    
2733.
                for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
2734.
                {
2735.
                    // Check if we are dealing with an array notation request
2736.
                    arrayNotation = a[i].match(__reArray);
2737.
                    funcNotation = a[i].match(__reFn);
2738.
    
2739.
                    if ( arrayNotation )
2740.
                    {
2741.
                        a[i] = a[i].replace(__reArray, '');
2742.
                        data[ a[i] ] = [];
2743.
    
2744.
                        // Get the remainder of the nested object to set so we can recurse
2745.
                        b = a.slice();
2746.
                        b.splice( 0, i+1 );
2747.
                        innerSrc = b.join('.');
2748.
    
2749.
                        // Traverse each entry in the array setting the properties requested
2750.
                        if ( $.isArray( val ) )
2751.
                        {
2752.
                            for ( var j=0, jLen=val.length ; j<jLen ; j++ )
2753.
                            {
2754.
                                o = {};
2755.
                                setData( o, val[j], innerSrc );
2756.
                                data[ a[i] ].push( o );
2757.
                            }
2758.
                        }
2759.
                        else
2760.
                        {
2761.
                            // We've been asked to save data to an array, but it
2762.
                            // isn't array data to be saved. Best that can be done
2763.
                            // is to just save the value.
2764.
                            data[ a[i] ] = val;
2765.
                        }
2766.
    
2767.
                        // The inner call to setData has already traversed through the remainder
2768.
                        // of the source and has set the data, thus we can exit here
2769.
                        return;
2770.
                    }
2771.
                    else if ( funcNotation )
2772.
                    {
2773.
                        // Function call
2774.
                        a[i] = a[i].replace(__reFn, '');
2775.
                        data = data[ a[i] ]( val );
2776.
                    }
2777.
    
2778.
                    // If the nested object doesn't currently exist - since we are
2779.
                    // trying to set the value - create it
2780.
                    if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
2781.
                    {
2782.
                        data[ a[i] ] = {};
2783.
                    }
2784.
                    data = data[ a[i] ];
2785.
                }
2786.
    
2787.
                // Last item in the input - i.e, the actual set
2788.
                if ( aLast.match(__reFn ) )
2789.
                {
2790.
                    // Function call
2791.
                    data = data[ aLast.replace(__reFn, '') ]( val );
2792.
                }
2793.
                else
2794.
                {
2795.
                    // If array notation is used, we just want to strip it and use the property name
2796.
                    // and assign the value. If it isn't used, then we get the result we want anyway
2797.
                    data[ aLast.replace(__reArray, '') ] = val;
2798.
                }
2799.
            };
2800.
    
2801.
            return function (data, val) { // meta is also passed in, but not used
2802.
                return setData( data, val, mSource );
2803.
            };
2804.
        }
2805.
        else
2806.
        {
2807.
            /* Array or flat object mapping */
2808.
            return function (data, val) { // meta is also passed in, but not used
2809.
                data[mSource] = val;
2810.
            };
2811.
        }
2812.
    }
2813.
    
2814.
    
2815.
    /**
2816.
     * Return an array with the full table data
2817.
     *  @param {object} oSettings dataTables settings object
2818.
     *  @returns array {array} aData Master data array
2819.
     *  @memberof DataTable#oApi
2820.
     */
2821.
    function _fnGetDataMaster ( settings )
2822.
    {
2823.
        return _pluck( settings.aoData, '_aData' );
2824.
    }
2825.
    
2826.
    
2827.
    /**
2828.
     * Nuke the table
2829.
     *  @param {object} oSettings dataTables settings object
2830.
     *  @memberof DataTable#oApi
2831.
     */
2832.
    function _fnClearTable( settings )
2833.
    {
2834.
        settings.aoData.length = 0;
2835.
        settings.aiDisplayMaster.length = 0;
2836.
        settings.aiDisplay.length = 0;
2837.
        settings.aIds = {};
2838.
    }
2839.
    
2840.
    
2841.
     /**
2842.
     * Take an array of integers (index array) and remove a target integer (value - not
2843.
     * the key!)
2844.
     *  @param {array} a Index array to target
2845.
     *  @param {int} iTarget value to find
2846.
     *  @memberof DataTable#oApi
2847.
     */
2848.
    function _fnDeleteIndex( a, iTarget, splice )
2849.
    {
2850.
        var iTargetIndex = -1;
2851.
    
2852.
        for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2853.
        {
2854.
            if ( a[i] == iTarget )
2855.
            {
2856.
                iTargetIndex = i;
2857.
            }
2858.
            else if ( a[i] > iTarget )
2859.
            {
2860.
                a[i]--;
2861.
            }
2862.
        }
2863.
    
2864.
        if ( iTargetIndex != -1 && splice === undefined )
2865.
        {
2866.
            a.splice( iTargetIndex, 1 );
2867.
        }
2868.
    }
2869.
    
2870.
    
2871.
    /**
2872.
     * Mark cached data as invalid such that a re-read of the data will occur when
2873.
     * the cached data is next requested. Also update from the data source object.
2874.
     *
2875.
     * @param {object} settings DataTables settings object
2876.
     * @param {int}    rowIdx   Row index to invalidate
2877.
     * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
2878.
     *     or 'data'
2879.
     * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
2880.
     *     row will be invalidated
2881.
     * @memberof DataTable#oApi
2882.
     *
2883.
     * @todo For the modularisation of v1.11 this will need to become a callback, so
2884.
     *   the sort and filter methods can subscribe to it. That will required
2885.
     *   initialisation options for sorting, which is why it is not already baked in
2886.
     */
2887.
    function _fnInvalidate( settings, rowIdx, src, colIdx )
2888.
    {
2889.
        var row = settings.aoData[ rowIdx ];
2890.
        var i, ien;
2891.
        var cellWrite = function ( cell, col ) {
2892.
            // This is very frustrating, but in IE if you just write directly
2893.
            // to innerHTML, and elements that are overwritten are GC'ed,
2894.
            // even if there is a reference to them elsewhere
2895.
            while ( cell.childNodes.length ) {
2896.
                cell.removeChild( cell.firstChild );
2897.
            }
2898.
    
2899.
            cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
2900.
        };
2901.
    
2902.
        // Are we reading last data from DOM or the data object?
2903.
        if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
2904.
            // Read the data from the DOM
2905.
            row._aData = _fnGetRowElements(
2906.
                    settings, row, colIdx, colIdx === undefined ? undefined : row._aData
2907.
                )
2908.
                .data;
2909.
        }
2910.
        else {
2911.
            // Reading from data object, update the DOM
2912.
            var cells = row.anCells;
2913.
    
2914.
            if ( cells ) {
2915.
                if ( colIdx !== undefined ) {
2916.
                    cellWrite( cells[colIdx], colIdx );
2917.
                }
2918.
                else {
2919.
                    for ( i=0, ien=cells.length ; i<ien ; i++ ) {
2920.
                        cellWrite( cells[i], i );
2921.
                    }
2922.
                }
2923.
            }
2924.
        }
2925.
    
2926.
        // For both row and cell invalidation, the cached data for sorting and
2927.
        // filtering is nulled out
2928.
        row._aSortData = null;
2929.
        row._aFilterData = null;
2930.
    
2931.
        // Invalidate the type for a specific column (if given) or all columns since
2932.
        // the data might have changed
2933.
        var cols = settings.aoColumns;
2934.
        if ( colIdx !== undefined ) {
2935.
            cols[ colIdx ].sType = null;
2936.
        }
2937.
        else {
2938.
            for ( i=0, ien=cols.length ; i<ien ; i++ ) {
2939.
                cols[i].sType = null;
2940.
            }
2941.
    
2942.
            // Update DataTables special `DT_*` attributes for the row
2943.
            _fnRowAttributes( settings, row );
2944.
        }
2945.
    }
2946.
    
2947.
    
2948.
    /**
2949.
     * Build a data source object from an HTML row, reading the contents of the
2950.
     * cells that are in the row.
2951.
     *
2952.
     * @param {object} settings DataTables settings object
2953.
     * @param {node|object} TR element from which to read data or existing row
2954.
     *   object from which to re-read the data from the cells
2955.
     * @param {int} [colIdx] Optional column index
2956.
     * @param {array|object} [d] Data source object. If `colIdx` is given then this
2957.
     *   parameter should also be given and will be used to write the data into.
2958.
     *   Only the column in question will be written
2959.
     * @returns {object} Object with two parameters: `data` the data read, in
2960.
     *   document order, and `cells` and array of nodes (they can be useful to the
2961.
     *   caller, so rather than needing a second traversal to get them, just return
2962.
     *   them from here).
2963.
     * @memberof DataTable#oApi
2964.
     */
2965.
    function _fnGetRowElements( settings, row, colIdx, d )
2966.
    {
2967.
        var
2968.
            tds = [],
2969.
            td = row.firstChild,
2970.
            name, col, o, i=0, contents,
2971.
            columns = settings.aoColumns,
2972.
            objectRead = settings._rowReadObject;
2973.
    
2974.
        // Allow the data object to be passed in, or construct
2975.
        d = d !== undefined ?
2976.
            d :
2977.
            objectRead ?
2978.
                {} :
2979.
                [];
2980.
    
2981.
        var attr = function ( str, td  ) {
2982.
            if ( typeof str === 'string' ) {
2983.
                var idx = str.indexOf('@');
2984.
    
2985.
                if ( idx !== -1 ) {
2986.
                    var attr = str.substring( idx+1 );
2987.
                    var setter = _fnSetObjectDataFn( str );
2988.
                    setter( d, td.getAttribute( attr ) );
2989.
                }
2990.
            }
2991.
        };
2992.
    
2993.
        // Read data from a cell and store into the data object
2994.
        var cellProcess = function ( cell ) {
2995.
            if ( colIdx === undefined || colIdx === i ) {
2996.
                col = columns[i];
2997.
                contents = $.trim(cell.innerHTML);
2998.
    
2999.
                if ( col && col._bAttrSrc ) {
3000.
                    var setter = _fnSetObjectDataFn( col.mData._ );
3001.
                    setter( d, contents );
3002.
    
3003.
                    attr( col.mData.sort, cell );
3004.
                    attr( col.mData.type, cell );
3005.
                    attr( col.mData.filter, cell );
3006.
                }
3007.
                else {
3008.
                    // Depending on the `data` option for the columns the data can
3009.
                    // be read to either an object or an array.
3010.
                    if ( objectRead ) {
3011.
                        if ( ! col._setter ) {
3012.
                            // Cache the setter function
3013.
                            col._setter = _fnSetObjectDataFn( col.mData );
3014.
                        }
3015.
                        col._setter( d, contents );
3016.
                    }
3017.
                    else {
3018.
                        d[i] = contents;
3019.
                    }
3020.
                }
3021.
            }
3022.
    
3023.
            i++;
3024.
        };
3025.
    
3026.
        if ( td ) {
3027.
            // `tr` element was passed in
3028.
            while ( td ) {
3029.
                name = td.nodeName.toUpperCase();
3030.
    
3031.
                if ( name == "TD" || name == "TH" ) {
3032.
                    cellProcess( td );
3033.
                    tds.push( td );
3034.
                }
3035.
    
3036.
                td = td.nextSibling;
3037.
            }
3038.
        }
3039.
        else {
3040.
            // Existing row object passed in
3041.
            tds = row.anCells;
3042.
    
3043.
            for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
3044.
                cellProcess( tds[j] );
3045.
            }
3046.
        }
3047.
    
3048.
        // Read the ID from the DOM if present
3049.
        var rowNode = row.firstChild ? row : row.nTr;
3050.
    
3051.
        if ( rowNode ) {
3052.
            var id = rowNode.getAttribute( 'id' );
3053.
    
3054.
            if ( id ) {
3055.
                _fnSetObjectDataFn( settings.rowId )( d, id );
3056.
            }
3057.
        }
3058.
    
3059.
        return {
3060.
            data: d,
3061.
            cells: tds
3062.
        };
3063.
    }
3064.
    /**
3065.
     * Create a new TR element (and it's TD children) for a row
3066.
     *  @param {object} oSettings dataTables settings object
3067.
     *  @param {int} iRow Row to consider
3068.
     *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
3069.
     *    DataTables will create a row automatically
3070.
     *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
3071.
     *    if nTr is.
3072.
     *  @memberof DataTable#oApi
3073.
     */
3074.
    function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
3075.
    {
3076.
        var
3077.
            row = oSettings.aoData[iRow],
3078.
            rowData = row._aData,
3079.
            cells = [],
3080.
            nTr, nTd, oCol,
3081.
            i, iLen, create;
3082.
    
3083.
        if ( row.nTr === null )
3084.
        {
3085.
            nTr = nTrIn || document.createElement('tr');
3086.
    
3087.
            row.nTr = nTr;
3088.
            row.anCells = cells;
3089.
    
3090.
            /* Use a private property on the node to allow reserve mapping from the node
3091.
             * to the aoData array for fast look up
3092.
             */
3093.
            nTr._DT_RowIndex = iRow;
3094.
    
3095.
            /* Special parameters can be given by the data source to be used on the row */
3096.
            _fnRowAttributes( oSettings, row );
3097.
    
3098.
            /* Process each column */
3099.
            for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
3100.
            {
3101.
                oCol = oSettings.aoColumns[i];
3102.
                create = nTrIn ? false : true;
3103.
    
3104.
                nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
3105.
                nTd._DT_CellIndex = {
3106.
                    row: iRow,
3107.
                    column: i
3108.
                };
3109.
                
3110.
                cells.push( nTd );
3111.
    
3112.
                // Need to create the HTML if new, or if a rendering function is defined
3113.
                if ( create || ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
3114.
                     (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
3115.
                )) {
3116.
                    nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
3117.
                }
3118.
    
3119.
                /* Add user defined class */
3120.
                if ( oCol.sClass )
3121.
                {
3122.
                    nTd.className += ' '+oCol.sClass;
3123.
                }
3124.
    
3125.
                // Visibility - add or remove as required
3126.
                if ( oCol.bVisible && ! nTrIn )
3127.
                {
3128.
                    nTr.appendChild( nTd );
3129.
                }
3130.
                else if ( ! oCol.bVisible && nTrIn )
3131.
                {
3132.
                    nTd.parentNode.removeChild( nTd );
3133.
                }
3134.
    
3135.
                if ( oCol.fnCreatedCell )
3136.
                {
3137.
                    oCol.fnCreatedCell.call( oSettings.oInstance,
3138.
                        nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
3139.
                    );
3140.
                }
3141.
            }
3142.
    
3143.
            _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
3144.
        }
3145.
    
3146.
        // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
3147.
        // and deployed
3148.
        row.nTr.setAttribute( 'role', 'row' );
3149.
    }
3150.
    
3151.
    
3152.
    /**
3153.
     * Add attributes to a row based on the special `DT_*` parameters in a data
3154.
     * source object.
3155.
     *  @param {object} settings DataTables settings object
3156.
     *  @param {object} DataTables row object for the row to be modified
3157.
     *  @memberof DataTable#oApi
3158.
     */
3159.
    function _fnRowAttributes( settings, row )
3160.
    {
3161.
        var tr = row.nTr;
3162.
        var data = row._aData;
3163.
    
3164.
        if ( tr ) {
3165.
            var id = settings.rowIdFn( data );
3166.
    
3167.
            if ( id ) {
3168.
                tr.id = id;
3169.
            }
3170.
    
3171.
            if ( data.DT_RowClass ) {
3172.
                // Remove any classes added by DT_RowClass before
3173.
                var a = data.DT_RowClass.split(' ');
3174.
                row.__rowc = row.__rowc ?
3175.
                    _unique( row.__rowc.concat( a ) ) :
3176.
                    a;
3177.
    
3178.
                $(tr)
3179.
                    .removeClass( row.__rowc.join(' ') )
3180.
                    .addClass( data.DT_RowClass );
3181.
            }
3182.
    
3183.
            if ( data.DT_RowAttr ) {
3184.
                $(tr).attr( data.DT_RowAttr );
3185.
            }
3186.
    
3187.
            if ( data.DT_RowData ) {
3188.
                $(tr).data( data.DT_RowData );
3189.
            }
3190.
        }
3191.
    }
3192.
    
3193.
    
3194.
    /**
3195.
     * Create the HTML header for the table
3196.
     *  @param {object} oSettings dataTables settings object
3197.
     *  @memberof DataTable#oApi
3198.
     */
3199.
    function _fnBuildHead( oSettings )
3200.
    {
3201.
        var i, ien, cell, row, column;
3202.
        var thead = oSettings.nTHead;
3203.
        var tfoot = oSettings.nTFoot;
3204.
        var createHeader = $('th, td', thead).length === 0;
3205.
        var classes = oSettings.oClasses;
3206.
        var columns = oSettings.aoColumns;
3207.
    
3208.
        if ( createHeader ) {
3209.
            row = $('<tr/>').appendTo( thead );
3210.
        }
3211.
    
3212.
        for ( i=0, ien=columns.length ; i<ien ; i++ ) {
3213.
            column = columns[i];
3214.
            cell = $( column.nTh ).addClass( column.sClass );
3215.
    
3216.
            if ( createHeader ) {
3217.
                cell.appendTo( row );
3218.
            }
3219.
    
3220.
            // 1.11 move into sorting
3221.
            if ( oSettings.oFeatures.bSort ) {
3222.
                cell.addClass( column.sSortingClass );
3223.
    
3224.
                if ( column.bSortable !== false ) {
3225.
                    cell
3226.
                        .attr( 'tabindex', oSettings.iTabIndex )
3227.
                        .attr( 'aria-controls', oSettings.sTableId );
3228.
    
3229.
                    _fnSortAttachListener( oSettings, column.nTh, i );
3230.
                }
3231.
            }
3232.
    
3233.
            if ( column.sTitle != cell[0].innerHTML ) {
3234.
                cell.html( column.sTitle );
3235.
            }
3236.
    
3237.
            _fnRenderer( oSettings, 'header' )(
3238.
                oSettings, cell, column, classes
3239.
            );
3240.
        }
3241.
    
3242.
        if ( createHeader ) {
3243.
            _fnDetectHeader( oSettings.aoHeader, thead );
3244.
        }
3245.
        
3246.
        /* ARIA role for the rows */
3247.
         $(thead).find('>tr').attr('role', 'row');
3248.
    
3249.
        /* Deal with the footer - add classes if required */
3250.
        $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
3251.
        $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
3252.
    
3253.
        // Cache the footer cells. Note that we only take the cells from the first
3254.
        // row in the footer. If there is more than one row the user wants to
3255.
        // interact with, they need to use the table().foot() method. Note also this
3256.
        // allows cells to be used for multiple columns using colspan
3257.
        if ( tfoot !== null ) {
3258.
            var cells = oSettings.aoFooter[0];
3259.
    
3260.
            for ( i=0, ien=cells.length ; i<ien ; i++ ) {
3261.
                column = columns[i];
3262.
                column.nTf = cells[i].cell;
3263.
    
3264.
                if ( column.sClass ) {
3265.
                    $(column.nTf).addClass( column.sClass );
3266.
                }
3267.
            }
3268.
        }
3269.
    }
3270.
    
3271.
    
3272.
    /**
3273.
     * Draw the header (or footer) element based on the column visibility states. The
3274.
     * methodology here is to use the layout array from _fnDetectHeader, modified for
3275.
     * the instantaneous column visibility, to construct the new layout. The grid is
3276.
     * traversed over cell at a time in a rows x columns grid fashion, although each
3277.
     * cell insert can cover multiple elements in the grid - which is tracks using the
3278.
     * aApplied array. Cell inserts in the grid will only occur where there isn't
3279.
     * already a cell in that position.
3280.
     *  @param {object} oSettings dataTables settings object
3281.
     *  @param array {objects} aoSource Layout array from _fnDetectHeader
3282.
     *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
3283.
     *  @memberof DataTable#oApi
3284.
     */
3285.
    function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
3286.
    {
3287.
        var i, iLen, j, jLen, k, kLen, n, nLocalTr;
3288.
        var aoLocal = [];
3289.
        var aApplied = [];
3290.
        var iColumns = oSettings.aoColumns.length;
3291.
        var iRowspan, iColspan;
3292.
    
3293.
        if ( ! aoSource )
3294.
        {
3295.
            return;
3296.
        }
3297.
    
3298.
        if (  bIncludeHidden === undefined )
3299.
        {
3300.
            bIncludeHidden = false;
3301.
        }
3302.
    
3303.
        /* Make a copy of the master layout array, but without the visible columns in it */
3304.
        for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
3305.
        {
3306.
            aoLocal[i] = aoSource[i].slice();
3307.
            aoLocal[i].nTr = aoSource[i].nTr;
3308.
    
3309.
            /* Remove any columns which are currently hidden */
3310.
            for ( j=iColumns-1 ; j>=0 ; j-- )
3311.
            {
3312.
                if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
3313.
                {
3314.
                    aoLocal[i].splice( j, 1 );
3315.
                }
3316.
            }
3317.
    
3318.
            /* Prep the applied array - it needs an element for each row */
3319.
            aApplied.push( [] );
3320.
        }
3321.
    
3322.
        for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
3323.
        {
3324.
            nLocalTr = aoLocal[i].nTr;
3325.
    
3326.
            /* All cells are going to be replaced, so empty out the row */
3327.
            if ( nLocalTr )
3328.
            {
3329.
                while( (n = nLocalTr.firstChild) )
3330.
                {
3331.
                    nLocalTr.removeChild( n );
3332.
                }
3333.
            }
3334.
    
3335.
            for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
3336.
            {
3337.
                iRowspan = 1;
3338.
                iColspan = 1;
3339.
    
3340.
                /* Check to see if there is already a cell (row/colspan) covering our target
3341.
                 * insert point. If there is, then there is nothing to do.
3342.
                 */
3343.
                if ( aApplied[i][j] === undefined )
3344.
                {
3345.
                    nLocalTr.appendChild( aoLocal[i][j].cell );
3346.
                    aApplied[i][j] = 1;
3347.
    
3348.
                    /* Expand the cell to cover as many rows as needed */
3349.
                    while ( aoLocal[i+iRowspan] !== undefined &&
3350.
                            aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
3351.
                    {
3352.
                        aApplied[i+iRowspan][j] = 1;
3353.
                        iRowspan++;
3354.
                    }
3355.
    
3356.
                    /* Expand the cell to cover as many columns as needed */
3357.
                    while ( aoLocal[i][j+iColspan] !== undefined &&
3358.
                            aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
3359.
                    {
3360.
                        /* Must update the applied array over the rows for the columns */
3361.
                        for ( k=0 ; k<iRowspan ; k++ )
3362.
                        {
3363.
                            aApplied[i+k][j+iColspan] = 1;
3364.
                        }
3365.
                        iColspan++;
3366.
                    }
3367.
    
3368.
                    /* Do the actual expansion in the DOM */
3369.
                    $(aoLocal[i][j].cell)
3370.
                        .attr('rowspan', iRowspan)
3371.
                        .attr('colspan', iColspan);
3372.
                }
3373.
            }
3374.
        }
3375.
    }
3376.
    
3377.
    
3378.
    /**
3379.
     * Insert the required TR nodes into the table for display
3380.
     *  @param {object} oSettings dataTables settings object
3381.
     *  @memberof DataTable#oApi
3382.
     */
3383.
    function _fnDraw( oSettings )
3384.
    {
3385.
        /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
3386.
        var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
3387.
        if ( $.inArray( false, aPreDraw ) !== -1 )
3388.
        {
3389.
            _fnProcessingDisplay( oSettings, false );
3390.
            return;
3391.
        }
3392.
    
3393.
        var i, iLen, n;
3394.
        var anRows = [];
3395.
        var iRowCount = 0;
3396.
        var asStripeClasses = oSettings.asStripeClasses;
3397.
        var iStripes = asStripeClasses.length;
3398.
        var iOpenRows = oSettings.aoOpenRows.length;
3399.
        var oLang = oSettings.oLanguage;
3400.
        var iInitDisplayStart = oSettings.iInitDisplayStart;
3401.
        var bServerSide = _fnDataSource( oSettings ) == 'ssp';
3402.
        var aiDisplay = oSettings.aiDisplay;
3403.
    
3404.
        oSettings.bDrawing = true;
3405.
    
3406.
        /* Check and see if we have an initial draw position from state saving */
3407.
        if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
3408.
        {
3409.
            oSettings._iDisplayStart = bServerSide ?
3410.
                iInitDisplayStart :
3411.
                iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
3412.
                    0 :
3413.
                    iInitDisplayStart;
3414.
    
3415.
            oSettings.iInitDisplayStart = -1;
3416.
        }
3417.
    
3418.
        var iDisplayStart = oSettings._iDisplayStart;
3419.
        var iDisplayEnd = oSettings.fnDisplayEnd();
3420.
    
3421.
        /* Server-side processing draw intercept */
3422.
        if ( oSettings.bDeferLoading )
3423.
        {
3424.
            oSettings.bDeferLoading = false;
3425.
            oSettings.iDraw++;
3426.
            _fnProcessingDisplay( oSettings, false );
3427.
        }
3428.
        else if ( !bServerSide )
3429.
        {
3430.
            oSettings.iDraw++;
3431.
        }
3432.
        else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
3433.
        {
3434.
            return;
3435.
        }
3436.
    
3437.
        if ( aiDisplay.length !== 0 )
3438.
        {
3439.
            var iStart = bServerSide ? 0 : iDisplayStart;
3440.
            var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
3441.
    
3442.
            for ( var j=iStart ; j<iEnd ; j++ )
3443.
            {
3444.
                var iDataIndex = aiDisplay[j];
3445.
                var aoData = oSettings.aoData[ iDataIndex ];
3446.
                if ( aoData.nTr === null )
3447.
                {
3448.
                    _fnCreateTr( oSettings, iDataIndex );
3449.
                }
3450.
    
3451.
                var nRow = aoData.nTr;
3452.
    
3453.
                /* Remove the old striping classes and then add the new one */
3454.
                if ( iStripes !== 0 )
3455.
                {
3456.
                    var sStripe = asStripeClasses[ iRowCount % iStripes ];
3457.
                    if ( aoData._sRowStripe != sStripe )
3458.
                    {
3459.
                        $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
3460.
                        aoData._sRowStripe = sStripe;
3461.
                    }
3462.
                }
3463.
    
3464.
                // Row callback functions - might want to manipulate the row
3465.
                // iRowCount and j are not currently documented. Are they at all
3466.
                // useful?
3467.
                _fnCallbackFire( oSettings, 'aoRowCallback', null,
3468.
                    [nRow, aoData._aData, iRowCount, j, iDataIndex] );
3469.
    
3470.
                anRows.push( nRow );
3471.
                iRowCount++;
3472.
            }
3473.
        }
3474.
        else
3475.
        {
3476.
            /* Table is empty - create a row with an empty message in it */
3477.
            var sZero = oLang.sZeroRecords;
3478.
            if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
3479.
            {
3480.
                sZero = oLang.sLoadingRecords;
3481.
            }
3482.
            else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
3483.
            {
3484.
                sZero = oLang.sEmptyTable;
3485.
            }
3486.
    
3487.
            anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
3488.
                .append( $('<td />', {
3489.
                    'valign':  'top',
3490.
                    'colSpan': _fnVisbleColumns( oSettings ),
3491.
                    'class':   oSettings.oClasses.sRowEmpty
3492.
                } ).html( sZero ) )[0];
3493.
        }
3494.
    
3495.
        /* Header and footer callbacks */
3496.
        _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
3497.
            _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3498.
    
3499.
        _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
3500.
            _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3501.
    
3502.
        var body = $(oSettings.nTBody);
3503.
    
3504.
        body.children().detach();
3505.
        body.append( $(anRows) );
3506.
    
3507.
        /* Call all required callback functions for the end of a draw */
3508.
        _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
3509.
    
3510.
        /* Draw is complete, sorting and filtering must be as well */
3511.
        oSettings.bSorted = false;
3512.
        oSettings.bFiltered = false;
3513.
        oSettings.bDrawing = false;
3514.
    }
3515.
    
3516.
    
3517.
    /**
3518.
     * Redraw the table - taking account of the various features which are enabled
3519.
     *  @param {object} oSettings dataTables settings object
3520.
     *  @param {boolean} [holdPosition] Keep the current paging position. By default
3521.
     *    the paging is reset to the first page
3522.
     *  @memberof DataTable#oApi
3523.
     */
3524.
    function _fnReDraw( settings, holdPosition )
3525.
    {
3526.
        var
3527.
            features = settings.oFeatures,
3528.
            sort     = features.bSort,
3529.
            filter   = features.bFilter;
3530.
    
3531.
        if ( sort ) {
3532.
            _fnSort( settings );
3533.
        }
3534.
    
3535.
        if ( filter ) {
3536.
            _fnFilterComplete( settings, settings.oPreviousSearch );
3537.
        }
3538.
        else {
3539.
            // No filtering, so we want to just use the display master
3540.
            settings.aiDisplay = settings.aiDisplayMaster.slice();
3541.
        }
3542.
    
3543.
        if ( holdPosition !== true ) {
3544.
            settings._iDisplayStart = 0;
3545.
        }
3546.
    
3547.
        // Let any modules know about the draw hold position state (used by
3548.
        // scrolling internally)
3549.
        settings._drawHold = holdPosition;
3550.
    
3551.
        _fnDraw( settings );
3552.
    
3553.
        settings._drawHold = false;
3554.
    }
3555.
    
3556.
    
3557.
    /**
3558.
     * Add the options to the page HTML for the table
3559.
     *  @param {object} oSettings dataTables settings object
3560.
     *  @memberof DataTable#oApi
3561.
     */
3562.
    function _fnAddOptionsHtml ( oSettings )
3563.
    {
3564.
        var classes = oSettings.oClasses;
3565.
        var table = $(oSettings.nTable);
3566.
        var holding = $('<div/>').insertBefore( table ); // Holding element for speed
3567.
        var features = oSettings.oFeatures;
3568.
    
3569.
        // All DataTables are wrapped in a div
3570.
        var insert = $('<div/>', {
3571.
            id:      oSettings.sTableId+'_wrapper',
3572.
            'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
3573.
        } );
3574.
    
3575.
        oSettings.nHolding = holding[0];
3576.
        oSettings.nTableWrapper = insert[0];
3577.
        oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
3578.
    
3579.
        /* Loop over the user set positioning and place the elements as needed */
3580.
        var aDom = oSettings.sDom.split('');
3581.
        var featureNode, cOption, nNewNode, cNext, sAttr, j;
3582.
        for ( var i=0 ; i<aDom.length ; i++ )
3583.
        {
3584.
            featureNode = null;
3585.
            cOption = aDom[i];
3586.
    
3587.
            if ( cOption == '<' )
3588.
            {
3589.
                /* New container div */
3590.
                nNewNode = $('<div/>')[0];
3591.
    
3592.
                /* Check to see if we should append an id and/or a class name to the container */
3593.
                cNext = aDom[i+1];
3594.
                if ( cNext == "'" || cNext == '"' )
3595.
                {
3596.
                    sAttr = "";
3597.
                    j = 2;
3598.
                    while ( aDom[i+j] != cNext )
3599.
                    {
3600.
                        sAttr += aDom[i+j];
3601.
                        j++;
3602.
                    }
3603.
    
3604.
                    /* Replace jQuery UI constants @todo depreciated */
3605.
                    if ( sAttr == "H" )
3606.
                    {
3607.
                        sAttr = classes.sJUIHeader;
3608.
                    }
3609.
                    else if ( sAttr == "F" )
3610.
                    {
3611.
                        sAttr = classes.sJUIFooter;
3612.
                    }
3613.
    
3614.
                    /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
3615.
                     * breaks the string into parts and applies them as needed
3616.
                     */
3617.
                    if ( sAttr.indexOf('.') != -1 )
3618.
                    {
3619.
                        var aSplit = sAttr.split('.');
3620.
                        nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
3621.
                        nNewNode.className = aSplit[1];
3622.
                    }
3623.
                    else if ( sAttr.charAt(0) == "#" )
3624.
                    {
3625.
                        nNewNode.id = sAttr.substr(1, sAttr.length-1);
3626.
                    }
3627.
                    else
3628.
                    {
3629.
                        nNewNode.className = sAttr;
3630.
                    }
3631.
    
3632.
                    i += j; /* Move along the position array */
3633.
                }
3634.
    
3635.
                insert.append( nNewNode );
3636.
                insert = $(nNewNode);
3637.
            }
3638.
            else if ( cOption == '>' )
3639.
            {
3640.
                /* End container div */
3641.
                insert = insert.parent();
3642.
            }
3643.
            // @todo Move options into their own plugins?
3644.
            else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
3645.
            {
3646.
                /* Length */
3647.
                featureNode = _fnFeatureHtmlLength( oSettings );
3648.
            }
3649.
            else if ( cOption == 'f' && features.bFilter )
3650.
            {
3651.
                /* Filter */
3652.
                featureNode = _fnFeatureHtmlFilter( oSettings );
3653.
            }
3654.
            else if ( cOption == 'r' && features.bProcessing )
3655.
            {
3656.
                /* pRocessing */
3657.
                featureNode = _fnFeatureHtmlProcessing( oSettings );
3658.
            }
3659.
            else if ( cOption == 't' )
3660.
            {
3661.
                /* Table */
3662.
                featureNode = _fnFeatureHtmlTable( oSettings );
3663.
            }
3664.
            else if ( cOption ==  'i' && features.bInfo )
3665.
            {
3666.
                /* Info */
3667.
                featureNode = _fnFeatureHtmlInfo( oSettings );
3668.
            }
3669.
            else if ( cOption == 'p' && features.bPaginate )
3670.
            {
3671.
                /* Pagination */
3672.
                featureNode = _fnFeatureHtmlPaginate( oSettings );
3673.
            }
3674.
            else if ( DataTable.ext.feature.length !== 0 )
3675.
            {
3676.
                /* Plug-in features */
3677.
                var aoFeatures = DataTable.ext.feature;
3678.
                for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
3679.
                {
3680.
                    if ( cOption == aoFeatures[k].cFeature )
3681.
                    {
3682.
                        featureNode = aoFeatures[k].fnInit( oSettings );
3683.
                        break;
3684.
                    }
3685.
                }
3686.
            }
3687.
    
3688.
            /* Add to the 2D features array */
3689.
            if ( featureNode )
3690.
            {
3691.
                var aanFeatures = oSettings.aanFeatures;
3692.
    
3693.
                if ( ! aanFeatures[cOption] )
3694.
                {
3695.
                    aanFeatures[cOption] = [];
3696.
                }
3697.
    
3698.
                aanFeatures[cOption].push( featureNode );
3699.
                insert.append( featureNode );
3700.
            }
3701.
        }
3702.
    
3703.
        /* Built our DOM structure - replace the holding div with what we want */
3704.
        holding.replaceWith( insert );
3705.
        oSettings.nHolding = null;
3706.
    }
3707.
    
3708.
    
3709.
    /**
3710.
     * Use the DOM source to create up an array of header cells. The idea here is to
3711.
     * create a layout grid (array) of rows x columns, which contains a reference
3712.
     * to the cell that that point in the grid (regardless of col/rowspan), such that
3713.
     * any column / row could be removed and the new grid constructed
3714.
     *  @param array {object} aLayout Array to store the calculated layout in
3715.
     *  @param {node} nThead The header/footer element for the table
3716.
     *  @memberof DataTable#oApi
3717.
     */
3718.
    function _fnDetectHeader ( aLayout, nThead )
3719.
    {
3720.
        var nTrs = $(nThead).children('tr');
3721.
        var nTr, nCell;
3722.
        var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
3723.
        var bUnique;
3724.
        var fnShiftCol = function ( a, i, j ) {
3725.
            var k = a[i];
3726.
                    while ( k[j] ) {
3727.
                j++;
3728.
            }
3729.
            return j;
3730.
        };
3731.
    
3732.
        aLayout.splice( 0, aLayout.length );
3733.
    
3734.
        /* We know how many rows there are in the layout - so prep it */
3735.
        for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3736.
        {
3737.
            aLayout.push( [] );
3738.
        }
3739.
    
3740.
        /* Calculate a layout array */
3741.
        for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3742.
        {
3743.
            nTr = nTrs[i];
3744.
            iColumn = 0;
3745.
    
3746.
            /* For every cell in the row... */
3747.
            nCell = nTr.firstChild;
3748.
            while ( nCell ) {
3749.
                if ( nCell.nodeName.toUpperCase() == "TD" ||
3750.
                     nCell.nodeName.toUpperCase() == "TH" )
3751.
                {
3752.
                    /* Get the col and rowspan attributes from the DOM and sanitise them */
3753.
                    iColspan = nCell.getAttribute('colspan') * 1;
3754.
                    iRowspan = nCell.getAttribute('rowspan') * 1;
3755.
                    iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
3756.
                    iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
3757.
    
3758.
                    /* There might be colspan cells already in this row, so shift our target
3759.
                     * accordingly
3760.
                     */
3761.
                    iColShifted = fnShiftCol( aLayout, i, iColumn );
3762.
    
3763.
                    /* Cache calculation for unique columns */
3764.
                    bUnique = iColspan === 1 ? true : false;
3765.
    
3766.
                    /* If there is col / rowspan, copy the information into the layout grid */
3767.
                    for ( l=0 ; l<iColspan ; l++ )
3768.
                    {
3769.
                        for ( k=0 ; k<iRowspan ; k++ )
3770.
                        {
3771.
                            aLayout[i+k][iColShifted+l] = {
3772.
                                "cell": nCell,
3773.
                                "unique": bUnique
3774.
                            };
3775.
                            aLayout[i+k].nTr = nTr;
3776.
                        }
3777.
                    }
3778.
                }
3779.
                nCell = nCell.nextSibling;
3780.
            }
3781.
        }
3782.
    }
3783.
    
3784.
    
3785.
    /**
3786.
     * Get an array of unique th elements, one for each column
3787.
     *  @param {object} oSettings dataTables settings object
3788.
     *  @param {node} nHeader automatically detect the layout from this node - optional
3789.
     *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
3790.
     *  @returns array {node} aReturn list of unique th's
3791.
     *  @memberof DataTable#oApi
3792.
     */
3793.
    function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
3794.
    {
3795.
        var aReturn = [];
3796.
        if ( !aLayout )
3797.
        {
3798.
            aLayout = oSettings.aoHeader;
3799.
            if ( nHeader )
3800.
            {
3801.
                aLayout = [];
3802.
                _fnDetectHeader( aLayout, nHeader );
3803.
            }
3804.
        }
3805.
    
3806.
        for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
3807.
        {
3808.
            for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
3809.
            {
3810.
                if ( aLayout[i][j].unique &&
3811.
                     (!aReturn[j] || !oSettings.bSortCellsTop) )
3812.
                {
3813.
                    aReturn[j] = aLayout[i][j].cell;
3814.
                }
3815.
            }
3816.
        }
3817.
    
3818.
        return aReturn;
3819.
    }
3820.
    
3821.
    /**
3822.
     * Create an Ajax call based on the table's settings, taking into account that
3823.
     * parameters can have multiple forms, and backwards compatibility.
3824.
     *
3825.
     * @param {object} oSettings dataTables settings object
3826.
     * @param {array} data Data to send to the server, required by
3827.
     *     DataTables - may be augmented by developer callbacks
3828.
     * @param {function} fn Callback function to run when data is obtained
3829.
     */
3830.
    function _fnBuildAjax( oSettings, data, fn )
3831.
    {
3832.
        // Compatibility with 1.9-, allow fnServerData and event to manipulate
3833.
        _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
3834.
    
3835.
        // Convert to object based for 1.10+ if using the old array scheme which can
3836.
        // come from server-side processing or serverParams
3837.
        if ( data && $.isArray(data) ) {
3838.
            var tmp = {};
3839.
            var rbracket = /(.*?)\[\]$/;
3840.
    
3841.
            $.each( data, function (key, val) {
3842.
                var match = val.name.match(rbracket);
3843.
    
3844.
                if ( match ) {
3845.
                    // Support for arrays
3846.
                    var name = match[0];
3847.
    
3848.
                    if ( ! tmp[ name ] ) {
3849.
                        tmp[ name ] = [];
3850.
                    }
3851.
                    tmp[ name ].push( val.value );
3852.
                }
3853.
                else {
3854.
                    tmp[val.name] = val.value;
3855.
                }
3856.
            } );
3857.
            data = tmp;
3858.
        }
3859.
    
3860.
        var ajaxData;
3861.
        var ajax = oSettings.ajax;
3862.
        var instance = oSettings.oInstance;
3863.
        var callback = function ( json ) {
3864.
            _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
3865.
            fn( json );
3866.
        };
3867.
    
3868.
        if ( $.isPlainObject( ajax ) && ajax.data )
3869.
        {
3870.
            ajaxData = ajax.data;
3871.
    
3872.
            var newData = typeof ajaxData === 'function' ?
3873.
                ajaxData( data, oSettings ) :  // fn can manipulate data or return
3874.
                ajaxData;                      // an object object or array to merge
3875.
    
3876.
            // If the function returned something, use that alone
3877.
            data = typeof ajaxData === 'function' && newData ?
3878.
                newData :
3879.
                $.extend( true, data, newData );
3880.
    
3881.
            // Remove the data property as we've resolved it already and don't want
3882.
            // jQuery to do it again (it is restored at the end of the function)
3883.
            delete ajax.data;
3884.
        }
3885.
    
3886.
        var baseAjax = {
3887.
            "data": data,
3888.
            "success": function (json) {
3889.
                var error = json.error || json.sError;
3890.
                if ( error ) {
3891.
                    _fnLog( oSettings, 0, error );
3892.
                }
3893.
    
3894.
                oSettings.json = json;
3895.
                callback( json );
3896.
            },
3897.
            "dataType": "json",
3898.
            "cache": false,
3899.
            "type": oSettings.sServerMethod,
3900.
            "error": function (xhr, error, thrown) {
3901.
                var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
3902.
    
3903.
                if ( $.inArray( true, ret ) === -1 ) {
3904.
                    if ( error == "parsererror" ) {
3905.
                        _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
3906.
                    }
3907.
                    else if ( xhr.readyState === 4 ) {
3908.
                        _fnLog( oSettings, 0, 'Ajax error', 7 );
3909.
                    }
3910.
                }
3911.
    
3912.
                _fnProcessingDisplay( oSettings, false );
3913.
            }
3914.
        };
3915.
    
3916.
        // Store the data submitted for the API
3917.
        oSettings.oAjaxData = data;
3918.
    
3919.
        // Allow plug-ins and external processes to modify the data
3920.
        _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
3921.
    
3922.
        if ( oSettings.fnServerData )
3923.
        {
3924.
            // DataTables 1.9- compatibility
3925.
            oSettings.fnServerData.call( instance,
3926.
                oSettings.sAjaxSource,
3927.
                $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
3928.
                    return { name: key, value: val };
3929.
                } ),
3930.
                callback,
3931.
                oSettings
3932.
            );
3933.
        }
3934.
        else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
3935.
        {
3936.
            // DataTables 1.9- compatibility
3937.
            oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
3938.
                url: ajax || oSettings.sAjaxSource
3939.
            } ) );
3940.
        }
3941.
        else if ( typeof ajax === 'function' )
3942.
        {
3943.
            // Is a function - let the caller define what needs to be done
3944.
            oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
3945.
        }
3946.
        else
3947.
        {
3948.
            // Object to extend the base settings
3949.
            oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
3950.
    
3951.
            // Restore for next time around
3952.
            ajax.data = ajaxData;
3953.
        }
3954.
    }
3955.
    
3956.
    
3957.
    /**
3958.
     * Update the table using an Ajax call
3959.
     *  @param {object} settings dataTables settings object
3960.
     *  @returns {boolean} Block the table drawing or not
3961.
     *  @memberof DataTable#oApi
3962.
     */
3963.
    function _fnAjaxUpdate( settings )
3964.
    {
3965.
        if ( settings.bAjaxDataGet ) {
3966.
            settings.iDraw++;
3967.
            _fnProcessingDisplay( settings, true );
3968.
    
3969.
            _fnBuildAjax(
3970.
                settings,
3971.
                _fnAjaxParameters( settings ),
3972.
                function(json) {
3973.
                    _fnAjaxUpdateDraw( settings, json );
3974.
                }
3975.
            );
3976.
    
3977.
            return false;
3978.
        }
3979.
        return true;
3980.
    }
3981.
    
3982.
    
3983.
    /**
3984.
     * Build up the parameters in an object needed for a server-side processing
3985.
     * request. Note that this is basically done twice, is different ways - a modern
3986.
     * method which is used by default in DataTables 1.10 which uses objects and
3987.
     * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
3988.
     * the sAjaxSource option is used in the initialisation, or the legacyAjax
3989.
     * option is set.
3990.
     *  @param {object} oSettings dataTables settings object
3991.
     *  @returns {bool} block the table drawing or not
3992.
     *  @memberof DataTable#oApi
3993.
     */
3994.
    function _fnAjaxParameters( settings )
3995.
    {
3996.
        var
3997.
            columns = settings.aoColumns,
3998.
            columnCount = columns.length,
3999.
            features = settings.oFeatures,
4000.
            preSearch = settings.oPreviousSearch,
4001.
            preColSearch = settings.aoPreSearchCols,
4002.
            i, data = [], dataProp, column, columnSearch,
4003.
            sort = _fnSortFlatten( settings ),
4004.
            displayStart = settings._iDisplayStart,
4005.
            displayLength = features.bPaginate !== false ?
4006.
                settings._iDisplayLength :
4007.
                -1;
4008.
    
4009.
        var param = function ( name, value ) {
4010.
            data.push( { 'name': name, 'value': value } );
4011.
        };
4012.
    
4013.
        // DataTables 1.9- compatible method
4014.
        param( 'sEcho',          settings.iDraw );
4015.
        param( 'iColumns',       columnCount );
4016.
        param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
4017.
        param( 'iDisplayStart',  displayStart );
4018.
        param( 'iDisplayLength', displayLength );
4019.
    
4020.
        // DataTables 1.10+ method
4021.
        var d = {
4022.
            draw:    settings.iDraw,
4023.
            columns: [],
4024.
            order:   [],
4025.
            start:   displayStart,
4026.
            length:  displayLength,
4027.
            search:  {
4028.
                value: preSearch.sSearch,
4029.
                regex: preSearch.bRegex
4030.
            }
4031.
        };
4032.
    
4033.
        for ( i=0 ; i<columnCount ; i++ ) {
4034.
            column = columns[i];
4035.
            columnSearch = preColSearch[i];
4036.
            dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
4037.
    
4038.
            d.columns.push( {
4039.
                data:       dataProp,
4040.
                name:       column.sName,
4041.
                searchable: column.bSearchable,
4042.
                orderable:  column.bSortable,
4043.
                search:     {
4044.
                    value: columnSearch.sSearch,
4045.
                    regex: columnSearch.bRegex
4046.
                }
4047.
            } );
4048.
    
4049.
            param( "mDataProp_"+i, dataProp );
4050.
    
4051.
            if ( features.bFilter ) {
4052.
                param( 'sSearch_'+i,     columnSearch.sSearch );
4053.
                param( 'bRegex_'+i,      columnSearch.bRegex );
4054.
                param( 'bSearchable_'+i, column.bSearchable );
4055.
            }
4056.
    
4057.
            if ( features.bSort ) {
4058.
                param( 'bSortable_'+i, column.bSortable );
4059.
            }
4060.
        }
4061.
    
4062.
        if ( features.bFilter ) {
4063.
            param( 'sSearch', preSearch.sSearch );
4064.
            param( 'bRegex', preSearch.bRegex );
4065.
        }
4066.
    
4067.
        if ( features.bSort ) {
4068.
            $.each( sort, function ( i, val ) {
4069.
                d.order.push( { column: val.col, dir: val.dir } );
4070.
    
4071.
                param( 'iSortCol_'+i, val.col );
4072.
                param( 'sSortDir_'+i, val.dir );
4073.
            } );
4074.
    
4075.
            param( 'iSortingCols', sort.length );
4076.
        }
4077.
    
4078.
        // If the legacy.ajax parameter is null, then we automatically decide which
4079.
        // form to use, based on sAjaxSource
4080.
        var legacy = DataTable.ext.legacy.ajax;
4081.
        if ( legacy === null ) {
4082.
            return settings.sAjaxSource ? data : d;
4083.
        }
4084.
    
4085.
        // Otherwise, if legacy has been specified then we use that to decide on the
4086.
        // form
4087.
        return legacy ? data : d;
4088.
    }
4089.
    
4090.
    
4091.
    /**
4092.
     * Data the data from the server (nuking the old) and redraw the table
4093.
     *  @param {object} oSettings dataTables settings object
4094.
     *  @param {object} json json data return from the server.
4095.
     *  @param {string} json.sEcho Tracking flag for DataTables to match requests
4096.
     *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
4097.
     *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
4098.
     *  @param {array} json.aaData The data to display on this page
4099.
     *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
4100.
     *  @memberof DataTable#oApi
4101.
     */
4102.
    function _fnAjaxUpdateDraw ( settings, json )
4103.
    {
4104.
        // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
4105.
        // Support both
4106.
        var compat = function ( old, modern ) {
4107.
            return json[old] !== undefined ? json[old] : json[modern];
4108.
        };
4109.
    
4110.
        var data = _fnAjaxDataSrc( settings, json );
4111.
        var draw            = compat( 'sEcho',                'draw' );
4112.
        var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
4113.
        var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
4114.
    
4115.
        if ( draw !== undefined ) {
4116.
            // Protect against out of sequence returns
4117.
            if ( draw*1 < settings.iDraw ) {
4118.
                return;
4119.
            }
4120.
            settings.iDraw = draw * 1;
4121.
        }
4122.
    
4123.
        _fnClearTable( settings );
4124.
        settings._iRecordsTotal   = parseInt(recordsTotal, 10);
4125.
        settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
4126.
    
4127.
        for ( var i=0, ien=data.length ; i<ien ; i++ ) {
4128.
            _fnAddData( settings, data[i] );
4129.
        }
4130.
        settings.aiDisplay = settings.aiDisplayMaster.slice();
4131.
    
4132.
        settings.bAjaxDataGet = false;
4133.
        _fnDraw( settings );
4134.
    
4135.
        if ( ! settings._bInitComplete ) {
4136.
            _fnInitComplete( settings, json );
4137.
        }
4138.
    
4139.
        settings.bAjaxDataGet = true;
4140.
        _fnProcessingDisplay( settings, false );
4141.
    }
4142.
    
4143.
    
4144.
    /**
4145.
     * Get the data from the JSON data source to use for drawing a table. Using
4146.
     * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
4147.
     * source object, or from a processing function.
4148.
     *  @param {object} oSettings dataTables settings object
4149.
     *  @param  {object} json Data source object / array from the server
4150.
     *  @return {array} Array of data to use
4151.
     */
4152.
    function _fnAjaxDataSrc ( oSettings, json )
4153.
    {
4154.
        var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
4155.
            oSettings.ajax.dataSrc :
4156.
            oSettings.sAjaxDataProp; // Compatibility with 1.9-.
4157.
    
4158.
        // Compatibility with 1.9-. In order to read from aaData, check if the
4159.
        // default has been changed, if not, check for aaData
4160.
        if ( dataSrc === 'data' ) {
4161.
            return json.aaData || json[dataSrc];
4162.
        }
4163.
    
4164.
        return dataSrc !== "" ?
4165.
            _fnGetObjectDataFn( dataSrc )( json ) :
4166.
            json;
4167.
    }
4168.
    
4169.
    /**
4170.
     * Generate the node required for filtering text
4171.
     *  @returns {node} Filter control element
4172.
     *  @param {object} oSettings dataTables settings object
4173.
     *  @memberof DataTable#oApi
4174.
     */
4175.
    function _fnFeatureHtmlFilter ( settings )
4176.
    {
4177.
        var classes = settings.oClasses;
4178.
        var tableId = settings.sTableId;
4179.
        var language = settings.oLanguage;
4180.
        var previousSearch = settings.oPreviousSearch;
4181.
        var features = settings.aanFeatures;
4182.
        var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
4183.
    
4184.
        var str = language.sSearch;
4185.
        str = str.match(/_INPUT_/) ?
4186.
            str.replace('_INPUT_', input) :
4187.
            str+input;
4188.
    
4189.
        var filter = $('<div/>', {
4190.
                'id': ! features.f ? tableId+'_filter' : null,
4191.
                'class': classes.sFilter
4192.
            } )
4193.
            .append( $('<label/>' ).append( str ) );
4194.
    
4195.
        var searchFn = function() {
4196.
            /* Update all other filter input elements for the new display */
4197.
            var n = features.f;
4198.
            var val = !this.value ? "" : this.value; // mental IE8 fix :-(
4199.
    
4200.
            /* Now do the filter */
4201.
            if ( val != previousSearch.sSearch ) {
4202.
                _fnFilterComplete( settings, {
4203.
                    "sSearch": val,
4204.
                    "bRegex": previousSearch.bRegex,
4205.
                    "bSmart": previousSearch.bSmart ,
4206.
                    "bCaseInsensitive": previousSearch.bCaseInsensitive
4207.
                } );
4208.
    
4209.
                // Need to redraw, without resorting
4210.
                settings._iDisplayStart = 0;
4211.
                _fnDraw( settings );
4212.
            }
4213.
        };
4214.
    
4215.
        var searchDelay = settings.searchDelay !== null ?
4216.
            settings.searchDelay :
4217.
            _fnDataSource( settings ) === 'ssp' ?
4218.
                400 :
4219.
                0;
4220.
    
4221.
        var jqFilter = $('input', filter)
4222.
            .val( previousSearch.sSearch )
4223.
            .attr( 'placeholder', language.sSearchPlaceholder )
4224.
            .on(
4225.
                'keyup.DT search.DT input.DT paste.DT cut.DT',
4226.
                searchDelay ?
4227.
                    _fnThrottle( searchFn, searchDelay ) :
4228.
                    searchFn
4229.
            )
4230.
            .on( 'mouseup', function(e) {
4231.
                // Edge fix! Edge 17 does not trigger anything other than mouse events when clicking
4232.
                // on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`
4233.
                // checks the value to see if it has changed. In other browsers it won't have.
4234.
                setTimeout( function () {
4235.
                    searchFn.call(jqFilter[0]);
4236.
                }, 10);
4237.
            } )
4238.
            .on( 'keypress.DT', function(e) {
4239.
                /* Prevent form submission */
4240.
                if ( e.keyCode == 13 ) {
4241.
                    return false;
4242.
                }
4243.
            } )
4244.
            .attr('aria-controls', tableId);
4245.
    
4246.
        // Update the input elements whenever the table is filtered
4247.
        $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
4248.
            if ( settings === s ) {
4249.
                // IE9 throws an 'unknown error' if document.activeElement is used
4250.
                // inside an iframe or frame...
4251.
                try {
4252.
                    if ( jqFilter[0] !== document.activeElement ) {
4253.
                        jqFilter.val( previousSearch.sSearch );
4254.
                    }
4255.
                }
4256.
                catch ( e ) {}
4257.
            }
4258.
        } );
4259.
    
4260.
        return filter[0];
4261.
    }
4262.
    
4263.
    
4264.
    /**
4265.
     * Filter the table using both the global filter and column based filtering
4266.
     *  @param {object} oSettings dataTables settings object
4267.
     *  @param {object} oSearch search information
4268.
     *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
4269.
     *  @memberof DataTable#oApi
4270.
     */
4271.
    function _fnFilterComplete ( oSettings, oInput, iForce )
4272.
    {
4273.
        var oPrevSearch = oSettings.oPreviousSearch;
4274.
        var aoPrevSearch = oSettings.aoPreSearchCols;
4275.
        var fnSaveFilter = function ( oFilter ) {
4276.
            /* Save the filtering values */
4277.
            oPrevSearch.sSearch = oFilter.sSearch;
4278.
            oPrevSearch.bRegex = oFilter.bRegex;
4279.
            oPrevSearch.bSmart = oFilter.bSmart;
4280.
            oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
4281.
        };
4282.
        var fnRegex = function ( o ) {
4283.
            // Backwards compatibility with the bEscapeRegex option
4284.
            return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
4285.
        };
4286.
    
4287.
        // Resolve any column types that are unknown due to addition or invalidation
4288.
        // @todo As per sort - can this be moved into an event handler?
4289.
        _fnColumnTypes( oSettings );
4290.
    
4291.
        /* In server-side processing all filtering is done by the server, so no point hanging around here */
4292.
        if ( _fnDataSource( oSettings ) != 'ssp' )
4293.
        {
4294.
            /* Global filter */
4295.
            _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
4296.
            fnSaveFilter( oInput );
4297.
    
4298.
            /* Now do the individual column filter */
4299.
            for ( var i=0 ; i<aoPrevSearch.length ; i++ )
4300.
            {
4301.
                _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
4302.
                    aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
4303.
            }
4304.
    
4305.
            /* Custom filtering */
4306.
            _fnFilterCustom( oSettings );
4307.
        }
4308.
        else
4309.
        {
4310.
            fnSaveFilter( oInput );
4311.
        }
4312.
    
4313.
        /* Tell the draw function we have been filtering */
4314.
        oSettings.bFiltered = true;
4315.
        _fnCallbackFire( oSettings, null, 'search', [oSettings] );
4316.
    }
4317.
    
4318.
    
4319.
    /**
4320.
     * Apply custom filtering functions
4321.
     *  @param {object} oSettings dataTables settings object
4322.
     *  @memberof DataTable#oApi
4323.
     */
4324.
    function _fnFilterCustom( settings )
4325.
    {
4326.
        var filters = DataTable.ext.search;
4327.
        var displayRows = settings.aiDisplay;
4328.
        var row, rowIdx;
4329.
    
4330.
        for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
4331.
            var rows = [];
4332.
    
4333.
            // Loop over each row and see if it should be included
4334.
            for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
4335.
                rowIdx = displayRows[ j ];
4336.
                row = settings.aoData[ rowIdx ];
4337.
    
4338.
                if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
4339.
                    rows.push( rowIdx );
4340.
                }
4341.
            }
4342.
    
4343.
            // So the array reference doesn't break set the results into the
4344.
            // existing array
4345.
            displayRows.length = 0;
4346.
            $.merge( displayRows, rows );
4347.
        }
4348.
    }
4349.
    
4350.
    
4351.
    /**
4352.
     * Filter the table on a per-column basis
4353.
     *  @param {object} oSettings dataTables settings object
4354.
     *  @param {string} sInput string to filter on
4355.
     *  @param {int} iColumn column to filter
4356.
     *  @param {bool} bRegex treat search string as a regular expression or not
4357.
     *  @param {bool} bSmart use smart filtering or not
4358.
     *  @param {bool} bCaseInsensitive Do case insenstive matching or not
4359.
     *  @memberof DataTable#oApi
4360.
     */
4361.
    function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
4362.
    {
4363.
        if ( searchStr === '' ) {
4364.
            return;
4365.
        }
4366.
    
4367.
        var data;
4368.
        var out = [];
4369.
        var display = settings.aiDisplay;
4370.
        var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
4371.
    
4372.
        for ( var i=0 ; i<display.length ; i++ ) {
4373.
            data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4374.
    
4375.
            if ( rpSearch.test( data ) ) {
4376.
                out.push( display[i] );
4377.
            }
4378.
        }
4379.
    
4380.
        settings.aiDisplay = out;
4381.
    }
4382.
    
4383.
    
4384.
    /**
4385.
     * Filter the data table based on user input and draw the table
4386.
     *  @param {object} settings dataTables settings object
4387.
     *  @param {string} input string to filter on
4388.
     *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
4389.
     *  @param {bool} regex treat as a regular expression or not
4390.
     *  @param {bool} smart perform smart filtering or not
4391.
     *  @param {bool} caseInsensitive Do case insenstive matching or not
4392.
     *  @memberof DataTable#oApi
4393.
     */
4394.
    function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
4395.
    {
4396.
        var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
4397.
        var prevSearch = settings.oPreviousSearch.sSearch;
4398.
        var displayMaster = settings.aiDisplayMaster;
4399.
        var display, invalidated, i;
4400.
        var filtered = [];
4401.
    
4402.
        // Need to take account of custom filtering functions - always filter
4403.
        if ( DataTable.ext.search.length !== 0 ) {
4404.
            force = true;
4405.
        }
4406.
    
4407.
        // Check if any of the rows were invalidated
4408.
        invalidated = _fnFilterData( settings );
4409.
    
4410.
        // If the input is blank - we just want the full data set
4411.
        if ( input.length <= 0 ) {
4412.
            settings.aiDisplay = displayMaster.slice();
4413.
        }
4414.
        else {
4415.
            // New search - start from the master array
4416.
            if ( invalidated ||
4417.
                 force ||
4418.
                 regex ||
4419.
                 prevSearch.length > input.length ||
4420.
                 input.indexOf(prevSearch) !== 0 ||
4421.
                 settings.bSorted // On resort, the display master needs to be
4422.
                                  // re-filtered since indexes will have changed
4423.
            ) {
4424.
                settings.aiDisplay = displayMaster.slice();
4425.
            }
4426.
    
4427.
            // Search the display array
4428.
            display = settings.aiDisplay;
4429.
    
4430.
            for ( i=0 ; i<display.length ; i++ ) {
4431.
                if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
4432.
                    filtered.push( display[i] );
4433.
                }
4434.
            }
4435.
    
4436.
            settings.aiDisplay = filtered;
4437.
        }
4438.
    }
4439.
    
4440.
    
4441.
    /**
4442.
     * Build a regular expression object suitable for searching a table
4443.
     *  @param {string} sSearch string to search for
4444.
     *  @param {bool} bRegex treat as a regular expression or not
4445.
     *  @param {bool} bSmart perform smart filtering or not
4446.
     *  @param {bool} bCaseInsensitive Do case insensitive matching or not
4447.
     *  @returns {RegExp} constructed object
4448.
     *  @memberof DataTable#oApi
4449.
     */
4450.
    function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
4451.
    {
4452.
        search = regex ?
4453.
            search :
4454.
            _fnEscapeRegex( search );
4455.
        
4456.
        if ( smart ) {
4457.
            /* For smart filtering we want to allow the search to work regardless of
4458.
             * word order. We also want double quoted text to be preserved, so word
4459.
             * order is important - a la google. So this is what we want to
4460.
             * generate:
4461.
             * 
4462.
             * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
4463.
             */
4464.
            var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
4465.
                if ( word.charAt(0) === '"' ) {
4466.
                    var m = word.match( /^"(.*)"$/ );
4467.
                    word = m ? m[1] : word;
4468.
                }
4469.
    
4470.
                return word.replace('"', '');
4471.
            } );
4472.
    
4473.
            search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
4474.
        }
4475.
    
4476.
        return new RegExp( search, caseInsensitive ? 'i' : '' );
4477.
    }
4478.
    
4479.
    
4480.
    /**
4481.
     * Escape a string such that it can be used in a regular expression
4482.
     *  @param {string} sVal string to escape
4483.
     *  @returns {string} escaped string
4484.
     *  @memberof DataTable#oApi
4485.
     */
4486.
    var _fnEscapeRegex = DataTable.util.escapeRegex;
4487.
    
4488.
    var __filter_div = $('<div>')[0];
4489.
    var __filter_div_textContent = __filter_div.textContent !== undefined;
4490.
    
4491.
    // Update the filtering data for each row if needed (by invalidation or first run)
4492.
    function _fnFilterData ( settings )
4493.
    {
4494.
        var columns = settings.aoColumns;
4495.
        var column;
4496.
        var i, j, ien, jen, filterData, cellData, row;
4497.
        var fomatters = DataTable.ext.type.search;
4498.
        var wasInvalidated = false;
4499.
    
4500.
        for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4501.
            row = settings.aoData[i];
4502.
    
4503.
            if ( ! row._aFilterData ) {
4504.
                filterData = [];
4505.
    
4506.
                for ( j=0, jen=columns.length ; j<jen ; j++ ) {
4507.
                    column = columns[j];
4508.
    
4509.
                    if ( column.bSearchable ) {
4510.
                        cellData = _fnGetCellData( settings, i, j, 'filter' );
4511.
    
4512.
                        if ( fomatters[ column.sType ] ) {
4513.
                            cellData = fomatters[ column.sType ]( cellData );
4514.
                        }
4515.
    
4516.
                        // Search in DataTables 1.10 is string based. In 1.11 this
4517.
                        // should be altered to also allow strict type checking.
4518.
                        if ( cellData === null ) {
4519.
                            cellData = '';
4520.
                        }
4521.
    
4522.
                        if ( typeof cellData !== 'string' && cellData.toString ) {
4523.
                            cellData = cellData.toString();
4524.
                        }
4525.
                    }
4526.
                    else {
4527.
                        cellData = '';
4528.
                    }
4529.
    
4530.
                    // If it looks like there is an HTML entity in the string,
4531.
                    // attempt to decode it so sorting works as expected. Note that
4532.
                    // we could use a single line of jQuery to do this, but the DOM
4533.
                    // method used here is much faster http://jsperf.com/html-decode
4534.
                    if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
4535.
                        __filter_div.innerHTML = cellData;
4536.
                        cellData = __filter_div_textContent ?
4537.
                            __filter_div.textContent :
4538.
                            __filter_div.innerText;
4539.
                    }
4540.
    
4541.
                    if ( cellData.replace ) {
4542.
                        cellData = cellData.replace(/[\r\n\u2028]/g, '');
4543.
                    }
4544.
    
4545.
                    filterData.push( cellData );
4546.
                }
4547.
    
4548.
                row._aFilterData = filterData;
4549.
                row._sFilterRow = filterData.join('  ');
4550.
                wasInvalidated = true;
4551.
            }
4552.
        }
4553.
    
4554.
        return wasInvalidated;
4555.
    }
4556.
    
4557.
    
4558.
    /**
4559.
     * Convert from the internal Hungarian notation to camelCase for external
4560.
     * interaction
4561.
     *  @param {object} obj Object to convert
4562.
     *  @returns {object} Inverted object
4563.
     *  @memberof DataTable#oApi
4564.
     */
4565.
    function _fnSearchToCamel ( obj )
4566.
    {
4567.
        return {
4568.
            search:          obj.sSearch,
4569.
            smart:           obj.bSmart,
4570.
            regex:           obj.bRegex,
4571.
            caseInsensitive: obj.bCaseInsensitive
4572.
        };
4573.
    }
4574.
    
4575.
    
4576.
    
4577.
    /**
4578.
     * Convert from camelCase notation to the internal Hungarian. We could use the
4579.
     * Hungarian convert function here, but this is cleaner
4580.
     *  @param {object} obj Object to convert
4581.
     *  @returns {object} Inverted object
4582.
     *  @memberof DataTable#oApi
4583.
     */
4584.
    function _fnSearchToHung ( obj )
4585.
    {
4586.
        return {
4587.
            sSearch:          obj.search,
4588.
            bSmart:           obj.smart,
4589.
            bRegex:           obj.regex,
4590.
            bCaseInsensitive: obj.caseInsensitive
4591.
        };
4592.
    }
4593.
    
4594.
    /**
4595.
     * Generate the node required for the info display
4596.
     *  @param {object} oSettings dataTables settings object
4597.
     *  @returns {node} Information element
4598.
     *  @memberof DataTable#oApi
4599.
     */
4600.
    function _fnFeatureHtmlInfo ( settings )
4601.
    {
4602.
        var
4603.
            tid = settings.sTableId,
4604.
            nodes = settings.aanFeatures.i,
4605.
            n = $('<div/>', {
4606.
                'class': settings.oClasses.sInfo,
4607.
                'id': ! nodes ? tid+'_info' : null
4608.
            } );
4609.
    
4610.
        if ( ! nodes ) {
4611.
            // Update display on each draw
4612.
            settings.aoDrawCallback.push( {
4613.
                "fn": _fnUpdateInfo,
4614.
                "sName": "information"
4615.
            } );
4616.
    
4617.
            n
4618.
                .attr( 'role', 'status' )
4619.
                .attr( 'aria-live', 'polite' );
4620.
    
4621.
            // Table is described by our info div
4622.
            $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
4623.
        }
4624.
    
4625.
        return n[0];
4626.
    }
4627.
    
4628.
    
4629.
    /**
4630.
     * Update the information elements in the display
4631.
     *  @param {object} settings dataTables settings object
4632.
     *  @memberof DataTable#oApi
4633.
     */
4634.
    function _fnUpdateInfo ( settings )
4635.
    {
4636.
        /* Show information about the table */
4637.
        var nodes = settings.aanFeatures.i;
4638.
        if ( nodes.length === 0 ) {
4639.
            return;
4640.
        }
4641.
    
4642.
        var
4643.
            lang  = settings.oLanguage,
4644.
            start = settings._iDisplayStart+1,
4645.
            end   = settings.fnDisplayEnd(),
4646.
            max   = settings.fnRecordsTotal(),
4647.
            total = settings.fnRecordsDisplay(),
4648.
            out   = total ?
4649.
                lang.sInfo :
4650.
                lang.sInfoEmpty;
4651.
    
4652.
        if ( total !== max ) {
4653.
            /* Record set after filtering */
4654.
            out += ' ' + lang.sInfoFiltered;
4655.
        }
4656.
    
4657.
        // Convert the macros
4658.
        out += lang.sInfoPostFix;
4659.
        out = _fnInfoMacros( settings, out );
4660.
    
4661.
        var callback = lang.fnInfoCallback;
4662.
        if ( callback !== null ) {
4663.
            out = callback.call( settings.oInstance,
4664.
                settings, start, end, max, total, out
4665.
            );
4666.
        }
4667.
    
4668.
        $(nodes).html( out );
4669.
    }
4670.
    
4671.
    
4672.
    function _fnInfoMacros ( settings, str )
4673.
    {
4674.
        // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
4675.
        // internally
4676.
        var
4677.
            formatter  = settings.fnFormatNumber,
4678.
            start      = settings._iDisplayStart+1,
4679.
            len        = settings._iDisplayLength,
4680.
            vis        = settings.fnRecordsDisplay(),
4681.
            all        = len === -1;
4682.
    
4683.
        return str.
4684.
            replace(/_START_/g, formatter.call( settings, start ) ).
4685.
            replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
4686.
            replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
4687.
            replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
4688.
            replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
4689.
            replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
4690.
    }
4691.
    
4692.
    
4693.
    
4694.
    /**
4695.
     * Draw the table for the first time, adding all required features
4696.
     *  @param {object} settings dataTables settings object
4697.
     *  @memberof DataTable#oApi
4698.
     */
4699.
    function _fnInitialise ( settings )
4700.
    {
4701.
        var i, iLen, iAjaxStart=settings.iInitDisplayStart;
4702.
        var columns = settings.aoColumns, column;
4703.
        var features = settings.oFeatures;
4704.
        var deferLoading = settings.bDeferLoading; // value modified by the draw
4705.
    
4706.
        /* Ensure that the table data is fully initialised */
4707.
        if ( ! settings.bInitialised ) {
4708.
            setTimeout( function(){ _fnInitialise( settings ); }, 200 );
4709.
            return;
4710.
        }
4711.
    
4712.
        /* Show the display HTML options */
4713.
        _fnAddOptionsHtml( settings );
4714.
    
4715.
        /* Build and draw the header / footer for the table */
4716.
        _fnBuildHead( settings );
4717.
        _fnDrawHead( settings, settings.aoHeader );
4718.
        _fnDrawHead( settings, settings.aoFooter );
4719.
    
4720.
        /* Okay to show that something is going on now */
4721.
        _fnProcessingDisplay( settings, true );
4722.
    
4723.
        /* Calculate sizes for columns */
4724.
        if ( features.bAutoWidth ) {
4725.
            _fnCalculateColumnWidths( settings );
4726.
        }
4727.
    
4728.
        for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
4729.
            column = columns[i];
4730.
    
4731.
            if ( column.sWidth ) {
4732.
                column.nTh.style.width = _fnStringToCss( column.sWidth );
4733.
            }
4734.
        }
4735.
    
4736.
        _fnCallbackFire( settings, null, 'preInit', [settings] );
4737.
    
4738.
        // If there is default sorting required - let's do it. The sort function
4739.
        // will do the drawing for us. Otherwise we draw the table regardless of the
4740.
        // Ajax source - this allows the table to look initialised for Ajax sourcing
4741.
        // data (show 'loading' message possibly)
4742.
        _fnReDraw( settings );
4743.
    
4744.
        // Server-side processing init complete is done by _fnAjaxUpdateDraw
4745.
        var dataSrc = _fnDataSource( settings );
4746.
        if ( dataSrc != 'ssp' || deferLoading ) {
4747.
            // if there is an ajax source load the data
4748.
            if ( dataSrc == 'ajax' ) {
4749.
                _fnBuildAjax( settings, [], function(json) {
4750.
                    var aData = _fnAjaxDataSrc( settings, json );
4751.
    
4752.
                    // Got the data - add it to the table
4753.
                    for ( i=0 ; i<aData.length ; i++ ) {
4754.
                        _fnAddData( settings, aData[i] );
4755.
                    }
4756.
    
4757.
                    // Reset the init display for cookie saving. We've already done
4758.
                    // a filter, and therefore cleared it before. So we need to make
4759.
                    // it appear 'fresh'
4760.
                    settings.iInitDisplayStart = iAjaxStart;
4761.
    
4762.
                    _fnReDraw( settings );
4763.
    
4764.
                    _fnProcessingDisplay( settings, false );
4765.
                    _fnInitComplete( settings, json );
4766.
                }, settings );
4767.
            }
4768.
            else {
4769.
                _fnProcessingDisplay( settings, false );
4770.
                _fnInitComplete( settings );
4771.
            }
4772.
        }
4773.
    }
4774.
    
4775.
    
4776.
    /**
4777.
     * Draw the table for the first time, adding all required features
4778.
     *  @param {object} oSettings dataTables settings object
4779.
     *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
4780.
     *    with client-side processing (optional)
4781.
     *  @memberof DataTable#oApi
4782.
     */
4783.
    function _fnInitComplete ( settings, json )
4784.
    {
4785.
        settings._bInitComplete = true;
4786.
    
4787.
        // When data was added after the initialisation (data or Ajax) we need to
4788.
        // calculate the column sizing
4789.
        if ( json || settings.oInit.aaData ) {
4790.
            _fnAdjustColumnSizing( settings );
4791.
        }
4792.
    
4793.
        _fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
4794.
        _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
4795.
    }
4796.
    
4797.
    
4798.
    function _fnLengthChange ( settings, val )
4799.
    {
4800.
        var len = parseInt( val, 10 );
4801.
        settings._iDisplayLength = len;
4802.
    
4803.
        _fnLengthOverflow( settings );
4804.
    
4805.
        // Fire length change event
4806.
        _fnCallbackFire( settings, null, 'length', [settings, len] );
4807.
    }
4808.
    
4809.
    
4810.
    /**
4811.
     * Generate the node required for user display length changing
4812.
     *  @param {object} settings dataTables settings object
4813.
     *  @returns {node} Display length feature node
4814.
     *  @memberof DataTable#oApi
4815.
     */
4816.
    function _fnFeatureHtmlLength ( settings )
4817.
    {
4818.
        var
4819.
            classes  = settings.oClasses,
4820.
            tableId  = settings.sTableId,
4821.
            menu     = settings.aLengthMenu,
4822.
            d2       = $.isArray( menu[0] ),
4823.
            lengths  = d2 ? menu[0] : menu,
4824.
            language = d2 ? menu[1] : menu;
4825.
    
4826.
        var select = $('<select/>', {
4827.
            'name':          tableId+'_length',
4828.
            'aria-controls': tableId,
4829.
            'class':         classes.sLengthSelect
4830.
        } );
4831.
    
4832.
        for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
4833.
            select[0][ i ] = new Option(
4834.
                typeof language[i] === 'number' ?
4835.
                    settings.fnFormatNumber( language[i] ) :
4836.
                    language[i],
4837.
                lengths[i]
4838.
            );
4839.
        }
4840.
    
4841.
        var div = $('<div><label/></div>').addClass( classes.sLength );
4842.
        if ( ! settings.aanFeatures.l ) {
4843.
            div[0].id = tableId+'_length';
4844.
        }
4845.
    
4846.
        div.children().append(
4847.
            settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
4848.
        );
4849.
    
4850.
        // Can't use `select` variable as user might provide their own and the
4851.
        // reference is broken by the use of outerHTML
4852.
        $('select', div)
4853.
            .val( settings._iDisplayLength )
4854.
            .on( 'change.DT', function(e) {
4855.
                _fnLengthChange( settings, $(this).val() );
4856.
                _fnDraw( settings );
4857.
            } );
4858.
    
4859.
        // Update node value whenever anything changes the table's length
4860.
        $(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
4861.
            if ( settings === s ) {
4862.
                $('select', div).val( len );
4863.
            }
4864.
        } );
4865.
    
4866.
        return div[0];
4867.
    }
4868.
    
4869.
    
4870.
    
4871.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4872.
     * Note that most of the paging logic is done in
4873.
     * DataTable.ext.pager
4874.
     */
4875.
    
4876.
    /**
4877.
     * Generate the node required for default pagination
4878.
     *  @param {object} oSettings dataTables settings object
4879.
     *  @returns {node} Pagination feature node
4880.
     *  @memberof DataTable#oApi
4881.
     */
4882.
    function _fnFeatureHtmlPaginate ( settings )
4883.
    {
4884.
        var
4885.
            type   = settings.sPaginationType,
4886.
            plugin = DataTable.ext.pager[ type ],
4887.
            modern = typeof plugin === 'function',
4888.
            redraw = function( settings ) {
4889.
                _fnDraw( settings );
4890.
            },
4891.
            node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
4892.
            features = settings.aanFeatures;
4893.
    
4894.
        if ( ! modern ) {
4895.
            plugin.fnInit( settings, node, redraw );
4896.
        }
4897.
    
4898.
        /* Add a draw callback for the pagination on first instance, to update the paging display */
4899.
        if ( ! features.p )
4900.
        {
4901.
            node.id = settings.sTableId+'_paginate';
4902.
    
4903.
            settings.aoDrawCallback.push( {
4904.
                "fn": function( settings ) {
4905.
                    if ( modern ) {
4906.
                        var
4907.
                            start      = settings._iDisplayStart,
4908.
                            len        = settings._iDisplayLength,
4909.
                            visRecords = settings.fnRecordsDisplay(),
4910.
                            all        = len === -1,
4911.
                            page = all ? 0 : Math.ceil( start / len ),
4912.
                            pages = all ? 1 : Math.ceil( visRecords / len ),
4913.
                            buttons = plugin(page, pages),
4914.
                            i, ien;
4915.
    
4916.
                        for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
4917.
                            _fnRenderer( settings, 'pageButton' )(
4918.
                                settings, features.p[i], i, buttons, page, pages
4919.
                            );
4920.
                        }
4921.
                    }
4922.
                    else {
4923.
                        plugin.fnUpdate( settings, redraw );
4924.
                    }
4925.
                },
4926.
                "sName": "pagination"
4927.
            } );
4928.
        }
4929.
    
4930.
        return node;
4931.
    }
4932.
    
4933.
    
4934.
    /**
4935.
     * Alter the display settings to change the page
4936.
     *  @param {object} settings DataTables settings object
4937.
     *  @param {string|int} action Paging action to take: "first", "previous",
4938.
     *    "next" or "last" or page number to jump to (integer)
4939.
     *  @param [bool] redraw Automatically draw the update or not
4940.
     *  @returns {bool} true page has changed, false - no change
4941.
     *  @memberof DataTable#oApi
4942.
     */
4943.
    function _fnPageChange ( settings, action, redraw )
4944.
    {
4945.
        var
4946.
            start     = settings._iDisplayStart,
4947.
            len       = settings._iDisplayLength,
4948.
            records   = settings.fnRecordsDisplay();
4949.
    
4950.
        if ( records === 0 || len === -1 )
4951.
        {
4952.
            start = 0;
4953.
        }
4954.
        else if ( typeof action === "number" )
4955.
        {
4956.
            start = action * len;
4957.
    
4958.
            if ( start > records )
4959.
            {
4960.
                start = 0;
4961.
            }
4962.
        }
4963.
        else if ( action == "first" )
4964.
        {
4965.
            start = 0;
4966.
        }
4967.
        else if ( action == "previous" )
4968.
        {
4969.
            start = len >= 0 ?
4970.
                start - len :
4971.
                0;
4972.
    
4973.
            if ( start < 0 )
4974.
            {
4975.
              start = 0;
4976.
            }
4977.
        }
4978.
        else if ( action == "next" )
4979.
        {
4980.
            if ( start + len < records )
4981.
            {
4982.
                start += len;
4983.
            }
4984.
        }
4985.
        else if ( action == "last" )
4986.
        {
4987.
            start = Math.floor( (records-1) / len) * len;
4988.
        }
4989.
        else
4990.
        {
4991.
            _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
4992.
        }
4993.
    
4994.
        var changed = settings._iDisplayStart !== start;
4995.
        settings._iDisplayStart = start;
4996.
    
4997.
        if ( changed ) {
4998.
            _fnCallbackFire( settings, null, 'page', [settings] );
4999.
    
5000.
            if ( redraw ) {
5001.
                _fnDraw( settings );
5002.
            }
5003.
        }
5004.
    
5005.
        return changed;
5006.
    }
5007.
    
5008.
    
5009.
    
5010.
    /**
5011.
     * Generate the node required for the processing node
5012.
     *  @param {object} settings dataTables settings object
5013.
     *  @returns {node} Processing element
5014.
     *  @memberof DataTable#oApi
5015.
     */
5016.
    function _fnFeatureHtmlProcessing ( settings )
5017.
    {
5018.
        return $('<div/>', {
5019.
                'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
5020.
                'class': settings.oClasses.sProcessing
5021.
            } )
5022.
            .html( settings.oLanguage.sProcessing )
5023.
            .insertBefore( settings.nTable )[0];
5024.
    }
5025.
    
5026.
    
5027.
    /**
5028.
     * Display or hide the processing indicator
5029.
     *  @param {object} settings dataTables settings object
5030.
     *  @param {bool} show Show the processing indicator (true) or not (false)
5031.
     *  @memberof DataTable#oApi
5032.
     */
5033.
    function _fnProcessingDisplay ( settings, show )
5034.
    {
5035.
        if ( settings.oFeatures.bProcessing ) {
5036.
            $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
5037.
        }
5038.
    
5039.
        _fnCallbackFire( settings, null, 'processing', [settings, show] );
5040.
    }
5041.
    
5042.
    /**
5043.
     * Add any control elements for the table - specifically scrolling
5044.
     *  @param {object} settings dataTables settings object
5045.
     *  @returns {node} Node to add to the DOM
5046.
     *  @memberof DataTable#oApi
5047.
     */
5048.
    function _fnFeatureHtmlTable ( settings )
5049.
    {
5050.
        var table = $(settings.nTable);
5051.
    
5052.
        // Add the ARIA grid role to the table
5053.
        table.attr( 'role', 'grid' );
5054.
    
5055.
        // Scrolling from here on in
5056.
        var scroll = settings.oScroll;
5057.
    
5058.
        if ( scroll.sX === '' && scroll.sY === '' ) {
5059.
            return settings.nTable;
5060.
        }
5061.
    
5062.
        var scrollX = scroll.sX;
5063.
        var scrollY = scroll.sY;
5064.
        var classes = settings.oClasses;
5065.
        var caption = table.children('caption');
5066.
        var captionSide = caption.length ? caption[0]._captionSide : null;
5067.
        var headerClone = $( table[0].cloneNode(false) );
5068.
        var footerClone = $( table[0].cloneNode(false) );
5069.
        var footer = table.children('tfoot');
5070.
        var _div = '<div/>';
5071.
        var size = function ( s ) {
5072.
            return !s ? null : _fnStringToCss( s );
5073.
        };
5074.
    
5075.
        if ( ! footer.length ) {
5076.
            footer = null;
5077.
        }
5078.
    
5079.
        /*
5080.
         * The HTML structure that we want to generate in this function is:
5081.
         *  div - scroller
5082.
         *    div - scroll head
5083.
         *      div - scroll head inner
5084.
         *        table - scroll head table
5085.
         *          thead - thead
5086.
         *    div - scroll body
5087.
         *      table - table (master table)
5088.
         *        thead - thead clone for sizing
5089.
         *        tbody - tbody
5090.
         *    div - scroll foot
5091.
         *      div - scroll foot inner
5092.
         *        table - scroll foot table
5093.
         *          tfoot - tfoot
5094.
         */
5095.
        var scroller = $( _div, { 'class': classes.sScrollWrapper } )
5096.
            .append(
5097.
                $(_div, { 'class': classes.sScrollHead } )
5098.
                    .css( {
5099.
                        overflow: 'hidden',
5100.
                        position: 'relative',
5101.
                        border: 0,
5102.
                        width: scrollX ? size(scrollX) : '100%'
5103.
                    } )
5104.
                    .append(
5105.
                        $(_div, { 'class': classes.sScrollHeadInner } )
5106.
                            .css( {
5107.
                                'box-sizing': 'content-box',
5108.
                                width: scroll.sXInner || '100%'
5109.
                            } )
5110.
                            .append(
5111.
                                headerClone
5112.
                                    .removeAttr('id')
5113.
                                    .css( 'margin-left', 0 )
5114.
                                    .append( captionSide === 'top' ? caption : null )
5115.
                                    .append(
5116.
                                        table.children('thead')
5117.
                                    )
5118.
                            )
5119.
                    )
5120.
            )
5121.
            .append(
5122.
                $(_div, { 'class': classes.sScrollBody } )
5123.
                    .css( {
5124.
                        position: 'relative',
5125.
                        overflow: 'auto',
5126.
                        width: size( scrollX )
5127.
                    } )
5128.
                    .append( table )
5129.
            );
5130.
    
5131.
        if ( footer ) {
5132.
            scroller.append(
5133.
                $(_div, { 'class': classes.sScrollFoot } )
5134.
                    .css( {
5135.
                        overflow: 'hidden',
5136.
                        border: 0,
5137.
                        width: scrollX ? size(scrollX) : '100%'
5138.
                    } )
5139.
                    .append(
5140.
                        $(_div, { 'class': classes.sScrollFootInner } )
5141.
                            .append(
5142.
                                footerClone
5143.
                                    .removeAttr('id')
5144.
                                    .css( 'margin-left', 0 )
5145.
                                    .append( captionSide === 'bottom' ? caption : null )
5146.
                                    .append(
5147.
                                        table.children('tfoot')
5148.
                                    )
5149.
                            )
5150.
                    )
5151.
            );
5152.
        }
5153.
    
5154.
        var children = scroller.children();
5155.
        var scrollHead = children[0];
5156.
        var scrollBody = children[1];
5157.
        var scrollFoot = footer ? children[2] : null;
5158.
    
5159.
        // When the body is scrolled, then we also want to scroll the headers
5160.
        if ( scrollX ) {
5161.
            $(scrollBody).on( 'scroll.DT', function (e) {
5162.
                var scrollLeft = this.scrollLeft;
5163.
    
5164.
                scrollHead.scrollLeft = scrollLeft;
5165.
    
5166.
                if ( footer ) {
5167.
                    scrollFoot.scrollLeft = scrollLeft;
5168.
                }
5169.
            } );
5170.
        }
5171.
    
5172.
        $(scrollBody).css('max-height', scrollY);
5173.
        if (! scroll.bCollapse) {
5174.
            $(scrollBody).css('height', scrollY);
5175.
        }
5176.
    
5177.
        settings.nScrollHead = scrollHead;
5178.
        settings.nScrollBody = scrollBody;
5179.
        settings.nScrollFoot = scrollFoot;
5180.
    
5181.
        // On redraw - align columns
5182.
        settings.aoDrawCallback.push( {
5183.
            "fn": _fnScrollDraw,
5184.
            "sName": "scrolling"
5185.
        } );
5186.
    
5187.
        return scroller[0];
5188.
    }
5189.
    
5190.
    
5191.
    
5192.
    /**
5193.
     * Update the header, footer and body tables for resizing - i.e. column
5194.
     * alignment.
5195.
     *
5196.
     * Welcome to the most horrible function DataTables. The process that this
5197.
     * function follows is basically:
5198.
     *   1. Re-create the table inside the scrolling div
5199.
     *   2. Take live measurements from the DOM
5200.
     *   3. Apply the measurements to align the columns
5201.
     *   4. Clean up
5202.
     *
5203.
     *  @param {object} settings dataTables settings object
5204.
     *  @memberof DataTable#oApi
5205.
     */
5206.
    function _fnScrollDraw ( settings )
5207.
    {
5208.
        // Given that this is such a monster function, a lot of variables are use
5209.
        // to try and keep the minimised size as small as possible
5210.
        var
5211.
            scroll         = settings.oScroll,
5212.
            scrollX        = scroll.sX,
5213.
            scrollXInner   = scroll.sXInner,
5214.
            scrollY        = scroll.sY,
5215.
            barWidth       = scroll.iBarWidth,
5216.
            divHeader      = $(settings.nScrollHead),
5217.
            divHeaderStyle = divHeader[0].style,
5218.
            divHeaderInner = divHeader.children('div'),
5219.
            divHeaderInnerStyle = divHeaderInner[0].style,
5220.
            divHeaderTable = divHeaderInner.children('table'),
5221.
            divBodyEl      = settings.nScrollBody,
5222.
            divBody        = $(divBodyEl),
5223.
            divBodyStyle   = divBodyEl.style,
5224.
            divFooter      = $(settings.nScrollFoot),
5225.
            divFooterInner = divFooter.children('div'),
5226.
            divFooterTable = divFooterInner.children('table'),
5227.
            header         = $(settings.nTHead),
5228.
            table          = $(settings.nTable),
5229.
            tableEl        = table[0],
5230.
            tableStyle     = tableEl.style,
5231.
            footer         = settings.nTFoot ? $(settings.nTFoot) : null,
5232.
            browser        = settings.oBrowser,
5233.
            ie67           = browser.bScrollOversize,
5234.
            dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
5235.
            headerTrgEls, footerTrgEls,
5236.
            headerSrcEls, footerSrcEls,
5237.
            headerCopy, footerCopy,
5238.
            headerWidths=[], footerWidths=[],
5239.
            headerContent=[], footerContent=[],
5240.
            idx, correction, sanityWidth,
5241.
            zeroOut = function(nSizer) {
5242.
                var style = nSizer.style;
5243.
                style.paddingTop = "0";
5244.
                style.paddingBottom = "0";
5245.
                style.borderTopWidth = "0";
5246.
                style.borderBottomWidth = "0";
5247.
                style.height = 0;
5248.
            };
5249.
    
5250.
        // If the scrollbar visibility has changed from the last draw, we need to
5251.
        // adjust the column sizes as the table width will have changed to account
5252.
        // for the scrollbar
5253.
        var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
5254.
        
5255.
        if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
5256.
            settings.scrollBarVis = scrollBarVis;
5257.
            _fnAdjustColumnSizing( settings );
5258.
            return; // adjust column sizing will call this function again
5259.
        }
5260.
        else {
5261.
            settings.scrollBarVis = scrollBarVis;
5262.
        }
5263.
    
5264.
        /*
5265.
         * 1. Re-create the table inside the scrolling div
5266.
         */
5267.
    
5268.
        // Remove the old minimised thead and tfoot elements in the inner table
5269.
        table.children('thead, tfoot').remove();
5270.
    
5271.
        if ( footer ) {
5272.
            footerCopy = footer.clone().prependTo( table );
5273.
            footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
5274.
            footerSrcEls = footerCopy.find('tr');
5275.
        }
5276.
    
5277.
        // Clone the current header and footer elements and then place it into the inner table
5278.
        headerCopy = header.clone().prependTo( table );
5279.
        headerTrgEls = header.find('tr'); // original header is in its own table
5280.
        headerSrcEls = headerCopy.find('tr');
5281.
        headerCopy.find('th, td').removeAttr('tabindex');
5282.
    
5283.
    
5284.
        /*
5285.
         * 2. Take live measurements from the DOM - do not alter the DOM itself!
5286.
         */
5287.
    
5288.
        // Remove old sizing and apply the calculated column widths
5289.
        // Get the unique column headers in the newly created (cloned) header. We want to apply the
5290.
        // calculated sizes to this header
5291.
        if ( ! scrollX )
5292.
        {
5293.
            divBodyStyle.width = '100%';
5294.
            divHeader[0].style.width = '100%';
5295.
        }
5296.
    
5297.
        $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
5298.
            idx = _fnVisibleToColumnIndex( settings, i );
5299.
            el.style.width = settings.aoColumns[idx].sWidth;
5300.
        } );
5301.
    
5302.
        if ( footer ) {
5303.
            _fnApplyToChildren( function(n) {
5304.
                n.style.width = "";
5305.
            }, footerSrcEls );
5306.
        }
5307.
    
5308.
        // Size the table as a whole
5309.
        sanityWidth = table.outerWidth();
5310.
        if ( scrollX === "" ) {
5311.
            // No x scrolling
5312.
            tableStyle.width = "100%";
5313.
    
5314.
            // IE7 will make the width of the table when 100% include the scrollbar
5315.
            // - which is shouldn't. When there is a scrollbar we need to take this
5316.
            // into account.
5317.
            if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
5318.
                divBody.css('overflow-y') == "scroll")
5319.
            ) {
5320.
                tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
5321.
            }
5322.
    
5323.
            // Recalculate the sanity width
5324.
            sanityWidth = table.outerWidth();
5325.
        }
5326.
        else if ( scrollXInner !== "" ) {
5327.
            // legacy x scroll inner has been given - use it
5328.
            tableStyle.width = _fnStringToCss(scrollXInner);
5329.
    
5330.
            // Recalculate the sanity width
5331.
            sanityWidth = table.outerWidth();
5332.
        }
5333.
    
5334.
        // Hidden header should have zero height, so remove padding and borders. Then
5335.
        // set the width based on the real headers
5336.
    
5337.
        // Apply all styles in one pass
5338.
        _fnApplyToChildren( zeroOut, headerSrcEls );
5339.
    
5340.
        // Read all widths in next pass
5341.
        _fnApplyToChildren( function(nSizer) {
5342.
            headerContent.push( nSizer.innerHTML );
5343.
            headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5344.
        }, headerSrcEls );
5345.
    
5346.
        // Apply all widths in final pass
5347.
        _fnApplyToChildren( function(nToSize, i) {
5348.
            // Only apply widths to the DataTables detected header cells - this
5349.
            // prevents complex headers from having contradictory sizes applied
5350.
            if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
5351.
                nToSize.style.width = headerWidths[i];
5352.
            }
5353.
        }, headerTrgEls );
5354.
    
5355.
        $(headerSrcEls).height(0);
5356.
    
5357.
        /* Same again with the footer if we have one */
5358.
        if ( footer )
5359.
        {
5360.
            _fnApplyToChildren( zeroOut, footerSrcEls );
5361.
    
5362.
            _fnApplyToChildren( function(nSizer) {
5363.
                footerContent.push( nSizer.innerHTML );
5364.
                footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5365.
            }, footerSrcEls );
5366.
    
5367.
            _fnApplyToChildren( function(nToSize, i) {
5368.
                nToSize.style.width = footerWidths[i];
5369.
            }, footerTrgEls );
5370.
    
5371.
            $(footerSrcEls).height(0);
5372.
        }
5373.
    
5374.
    
5375.
        /*
5376.
         * 3. Apply the measurements
5377.
         */
5378.
    
5379.
        // "Hide" the header and footer that we used for the sizing. We need to keep
5380.
        // the content of the cell so that the width applied to the header and body
5381.
        // both match, but we want to hide it completely. We want to also fix their
5382.
        // width to what they currently are
5383.
        _fnApplyToChildren( function(nSizer, i) {
5384.
            nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
5385.
            nSizer.childNodes[0].style.height = "0";
5386.
            nSizer.childNodes[0].style.overflow = "hidden";
5387.
            nSizer.style.width = headerWidths[i];
5388.
        }, headerSrcEls );
5389.
    
5390.
        if ( footer )
5391.
        {
5392.
            _fnApplyToChildren( function(nSizer, i) {
5393.
                nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
5394.
                nSizer.childNodes[0].style.height = "0";
5395.
                nSizer.childNodes[0].style.overflow = "hidden";
5396.
                nSizer.style.width = footerWidths[i];
5397.
            }, footerSrcEls );
5398.
        }
5399.
    
5400.
        // Sanity check that the table is of a sensible width. If not then we are going to get
5401.
        // misalignment - try to prevent this by not allowing the table to shrink below its min width
5402.
        if ( table.outerWidth() < sanityWidth )
5403.
        {
5404.
            // The min width depends upon if we have a vertical scrollbar visible or not */
5405.
            correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
5406.
                divBody.css('overflow-y') == "scroll")) ?
5407.
                    sanityWidth+barWidth :
5408.
                    sanityWidth;
5409.
    
5410.
            // IE6/7 are a law unto themselves...
5411.
            if ( ie67 && (divBodyEl.scrollHeight >
5412.
                divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
5413.
            ) {
5414.
                tableStyle.width = _fnStringToCss( correction-barWidth );
5415.
            }
5416.
    
5417.
            // And give the user a warning that we've stopped the table getting too small
5418.
            if ( scrollX === "" || scrollXInner !== "" ) {
5419.
                _fnLog( settings, 1, 'Possible column misalignment', 6 );
5420.
            }
5421.
        }
5422.
        else
5423.
        {
5424.
            correction = '100%';
5425.
        }
5426.
    
5427.
        // Apply to the container elements
5428.
        divBodyStyle.width = _fnStringToCss( correction );
5429.
        divHeaderStyle.width = _fnStringToCss( correction );
5430.
    
5431.
        if ( footer ) {
5432.
            settings.nScrollFoot.style.width = _fnStringToCss( correction );
5433.
        }
5434.
    
5435.
    
5436.
        /*
5437.
         * 4. Clean up
5438.
         */
5439.
        if ( ! scrollY ) {
5440.
            /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
5441.
             * the scrollbar height from the visible display, rather than adding it on. We need to
5442.
             * set the height in order to sort this. Don't want to do it in any other browsers.
5443.
             */
5444.
            if ( ie67 ) {
5445.
                divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
5446.
            }
5447.
        }
5448.
    
5449.
        /* Finally set the width's of the header and footer tables */
5450.
        var iOuterWidth = table.outerWidth();
5451.
        divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
5452.
        divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
5453.
    
5454.
        // Figure out if there are scrollbar present - if so then we need a the header and footer to
5455.
        // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5456.
        var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5457.
        var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
5458.
        divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
5459.
    
5460.
        if ( footer ) {
5461.
            divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
5462.
            divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
5463.
            divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
5464.
        }
5465.
    
5466.
        // Correct DOM ordering for colgroup - comes before the thead
5467.
        table.children('colgroup').insertBefore( table.children('thead') );
5468.
    
5469.
        /* Adjust the position of the header in case we loose the y-scrollbar */
5470.
        divBody.trigger('scroll');
5471.
    
5472.
        // If sorting or filtering has occurred, jump the scrolling back to the top
5473.
        // only if we aren't holding the position
5474.
        if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
5475.
            divBodyEl.scrollTop = 0;
5476.
        }
5477.
    }
5478.
    
5479.
    
5480.
    
5481.
    /**
5482.
     * Apply a given function to the display child nodes of an element array (typically
5483.
     * TD children of TR rows
5484.
     *  @param {function} fn Method to apply to the objects
5485.
     *  @param array {nodes} an1 List of elements to look through for display children
5486.
     *  @param array {nodes} an2 Another list (identical structure to the first) - optional
5487.
     *  @memberof DataTable#oApi
5488.
     */
5489.
    function _fnApplyToChildren( fn, an1, an2 )
5490.
    {
5491.
        var index=0, i=0, iLen=an1.length;
5492.
        var nNode1, nNode2;
5493.
    
5494.
        while ( i < iLen ) {
5495.
            nNode1 = an1[i].firstChild;
5496.
            nNode2 = an2 ? an2[i].firstChild : null;
5497.
    
5498.
            while ( nNode1 ) {
5499.
                if ( nNode1.nodeType === 1 ) {
5500.
                    if ( an2 ) {
5501.
                        fn( nNode1, nNode2, index );
5502.
                    }
5503.
                    else {
5504.
                        fn( nNode1, index );
5505.
                    }
5506.
    
5507.
                    index++;
5508.
                }
5509.
    
5510.
                nNode1 = nNode1.nextSibling;
5511.
                nNode2 = an2 ? nNode2.nextSibling : null;
5512.
            }
5513.
    
5514.
            i++;
5515.
        }
5516.
    }
5517.
    
5518.
    
5519.
    
5520.
    var __re_html_remove = /<.*?>/g;
5521.
    
5522.
    
5523.
    /**
5524.
     * Calculate the width of columns for the table
5525.
     *  @param {object} oSettings dataTables settings object
5526.
     *  @memberof DataTable#oApi
5527.
     */
5528.
    function _fnCalculateColumnWidths ( oSettings )
5529.
    {
5530.
        var
5531.
            table = oSettings.nTable,
5532.
            columns = oSettings.aoColumns,
5533.
            scroll = oSettings.oScroll,
5534.
            scrollY = scroll.sY,
5535.
            scrollX = scroll.sX,
5536.
            scrollXInner = scroll.sXInner,
5537.
            columnCount = columns.length,
5538.
            visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
5539.
            headerCells = $('th', oSettings.nTHead),
5540.
            tableWidthAttr = table.getAttribute('width'), // from DOM element
5541.
            tableContainer = table.parentNode,
5542.
            userInputs = false,
5543.
            i, column, columnIdx, width, outerWidth,
5544.
            browser = oSettings.oBrowser,
5545.
            ie67 = browser.bScrollOversize;
5546.
    
5547.
        var styleWidth = table.style.width;
5548.
        if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
5549.
            tableWidthAttr = styleWidth;
5550.
        }
5551.
    
5552.
        /* Convert any user input sizes into pixel sizes */
5553.
        for ( i=0 ; i<visibleColumns.length ; i++ ) {
5554.
            column = columns[ visibleColumns[i] ];
5555.
    
5556.
            if ( column.sWidth !== null ) {
5557.
                column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
5558.
    
5559.
                userInputs = true;
5560.
            }
5561.
        }
5562.
    
5563.
        /* If the number of columns in the DOM equals the number that we have to
5564.
         * process in DataTables, then we can use the offsets that are created by
5565.
         * the web- browser. No custom sizes can be set in order for this to happen,
5566.
         * nor scrolling used
5567.
         */
5568.
        if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
5569.
             columnCount == _fnVisbleColumns( oSettings ) &&
5570.
             columnCount == headerCells.length
5571.
        ) {
5572.
            for ( i=0 ; i<columnCount ; i++ ) {
5573.
                var colIdx = _fnVisibleToColumnIndex( oSettings, i );
5574.
    
5575.
                if ( colIdx !== null ) {
5576.
                    columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
5577.
                }
5578.
            }
5579.
        }
5580.
        else
5581.
        {
5582.
            // Otherwise construct a single row, worst case, table with the widest
5583.
            // node in the data, assign any user defined widths, then insert it into
5584.
            // the DOM and allow the browser to do all the hard work of calculating
5585.
            // table widths
5586.
            var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
5587.
                .css( 'visibility', 'hidden' )
5588.
                .removeAttr( 'id' );
5589.
    
5590.
            // Clean up the table body
5591.
            tmpTable.find('tbody tr').remove();
5592.
            var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
5593.
    
5594.
            // Clone the table header and footer - we can't use the header / footer
5595.
            // from the cloned table, since if scrolling is active, the table's
5596.
            // real header and footer are contained in different table tags
5597.
            tmpTable.find('thead, tfoot').remove();
5598.
            tmpTable
5599.
                .append( $(oSettings.nTHead).clone() )
5600.
                .append( $(oSettings.nTFoot).clone() );
5601.
    
5602.
            // Remove any assigned widths from the footer (from scrolling)
5603.
            tmpTable.find('tfoot th, tfoot td').css('width', '');
5604.
    
5605.
            // Apply custom sizing to the cloned header
5606.
            headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
5607.
    
5608.
            for ( i=0 ; i<visibleColumns.length ; i++ ) {
5609.
                column = columns[ visibleColumns[i] ];
5610.
    
5611.
                headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
5612.
                    _fnStringToCss( column.sWidthOrig ) :
5613.
                    '';
5614.
    
5615.
                // For scrollX we need to force the column width otherwise the
5616.
                // browser will collapse it. If this width is smaller than the
5617.
                // width the column requires, then it will have no effect
5618.
                if ( column.sWidthOrig && scrollX ) {
5619.
                    $( headerCells[i] ).append( $('<div/>').css( {
5620.
                        width: column.sWidthOrig,
5621.
                        margin: 0,
5622.
                        padding: 0,
5623.
                        border: 0,
5624.
                        height: 1
5625.
                    } ) );
5626.
                }
5627.
            }
5628.
    
5629.
            // Find the widest cell for each column and put it into the table
5630.
            if ( oSettings.aoData.length ) {
5631.
                for ( i=0 ; i<visibleColumns.length ; i++ ) {
5632.
                    columnIdx = visibleColumns[i];
5633.
                    column = columns[ columnIdx ];
5634.
    
5635.
                    $( _fnGetWidestNode( oSettings, columnIdx ) )
5636.
                        .clone( false )
5637.
                        .append( column.sContentPadding )
5638.
                        .appendTo( tr );
5639.
                }
5640.
            }
5641.
    
5642.
            // Tidy the temporary table - remove name attributes so there aren't
5643.
            // duplicated in the dom (radio elements for example)
5644.
            $('[name]', tmpTable).removeAttr('name');
5645.
    
5646.
            // Table has been built, attach to the document so we can work with it.
5647.
            // A holding element is used, positioned at the top of the container
5648.
            // with minimal height, so it has no effect on if the container scrolls
5649.
            // or not. Otherwise it might trigger scrolling when it actually isn't
5650.
            // needed
5651.
            var holder = $('<div/>').css( scrollX || scrollY ?
5652.
                    {
5653.
                        position: 'absolute',
5654.
                        top: 0,
5655.
                        left: 0,
5656.
                        height: 1,
5657.
                        right: 0,
5658.
                        overflow: 'hidden'
5659.
                    } :
5660.
                    {}
5661.
                )
5662.
                .append( tmpTable )
5663.
                .appendTo( tableContainer );
5664.
    
5665.
            // When scrolling (X or Y) we want to set the width of the table as 
5666.
            // appropriate. However, when not scrolling leave the table width as it
5667.
            // is. This results in slightly different, but I think correct behaviour
5668.
            if ( scrollX && scrollXInner ) {
5669.
                tmpTable.width( scrollXInner );
5670.
            }
5671.
            else if ( scrollX ) {
5672.
                tmpTable.css( 'width', 'auto' );
5673.
                tmpTable.removeAttr('width');
5674.
    
5675.
                // If there is no width attribute or style, then allow the table to
5676.
                // collapse
5677.
                if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
5678.
                    tmpTable.width( tableContainer.clientWidth );
5679.
                }
5680.
            }
5681.
            else if ( scrollY ) {
5682.
                tmpTable.width( tableContainer.clientWidth );
5683.
            }
5684.
            else if ( tableWidthAttr ) {
5685.
                tmpTable.width( tableWidthAttr );
5686.
            }
5687.
    
5688.
            // Get the width of each column in the constructed table - we need to
5689.
            // know the inner width (so it can be assigned to the other table's
5690.
            // cells) and the outer width so we can calculate the full width of the
5691.
            // table. This is safe since DataTables requires a unique cell for each
5692.
            // column, but if ever a header can span multiple columns, this will
5693.
            // need to be modified.
5694.
            var total = 0;
5695.
            for ( i=0 ; i<visibleColumns.length ; i++ ) {
5696.
                var cell = $(headerCells[i]);
5697.
                var border = cell.outerWidth() - cell.width();
5698.
    
5699.
                // Use getBounding... where possible (not IE8-) because it can give
5700.
                // sub-pixel accuracy, which we then want to round up!
5701.
                var bounding = browser.bBounding ?
5702.
                    Math.ceil( headerCells[i].getBoundingClientRect().width ) :
5703.
                    cell.outerWidth();
5704.
    
5705.
                // Total is tracked to remove any sub-pixel errors as the outerWidth
5706.
                // of the table might not equal the total given here (IE!).
5707.
                total += bounding;
5708.
    
5709.
                // Width for each column to use
5710.
                columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
5711.
            }
5712.
    
5713.
            table.style.width = _fnStringToCss( total );
5714.
    
5715.
            // Finished with the table - ditch it
5716.
            holder.remove();
5717.
        }
5718.
    
5719.
        // If there is a width attr, we want to attach an event listener which
5720.
        // allows the table sizing to automatically adjust when the window is
5721.
        // resized. Use the width attr rather than CSS, since we can't know if the
5722.
        // CSS is a relative value or absolute - DOM read is always px.
5723.
        if ( tableWidthAttr ) {
5724.
            table.style.width = _fnStringToCss( tableWidthAttr );
5725.
        }
5726.
    
5727.
        if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
5728.
            var bindResize = function () {
5729.
                $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
5730.
                    _fnAdjustColumnSizing( oSettings );
5731.
                } ) );
5732.
            };
5733.
    
5734.
            // IE6/7 will crash if we bind a resize event handler on page load.
5735.
            // To be removed in 1.11 which drops IE6/7 support
5736.
            if ( ie67 ) {
5737.
                setTimeout( bindResize, 1000 );
5738.
            }
5739.
            else {
5740.
                bindResize();
5741.
            }
5742.
    
5743.
            oSettings._reszEvt = true;
5744.
        }
5745.
    }
5746.
    
5747.
    
5748.
    /**
5749.
     * Throttle the calls to a function. Arguments and context are maintained for
5750.
     * the throttled function
5751.
     *  @param {function} fn Function to be called
5752.
     *  @param {int} [freq=200] call frequency in mS
5753.
     *  @returns {function} wrapped function
5754.
     *  @memberof DataTable#oApi
5755.
     */
5756.
    var _fnThrottle = DataTable.util.throttle;
5757.
    
5758.
    
5759.
    /**
5760.
     * Convert a CSS unit width to pixels (e.g. 2em)
5761.
     *  @param {string} width width to be converted
5762.
     *  @param {node} parent parent to get the with for (required for relative widths) - optional
5763.
     *  @returns {int} width in pixels
5764.
     *  @memberof DataTable#oApi
5765.
     */
5766.
    function _fnConvertToWidth ( width, parent )
5767.
    {
5768.
        if ( ! width ) {
5769.
            return 0;
5770.
        }
5771.
    
5772.
        var n = $('<div/>')
5773.
            .css( 'width', _fnStringToCss( width ) )
5774.
            .appendTo( parent || document.body );
5775.
    
5776.
        var val = n[0].offsetWidth;
5777.
        n.remove();
5778.
    
5779.
        return val;
5780.
    }
5781.
    
5782.
    
5783.
    /**
5784.
     * Get the widest node
5785.
     *  @param {object} settings dataTables settings object
5786.
     *  @param {int} colIdx column of interest
5787.
     *  @returns {node} widest table node
5788.
     *  @memberof DataTable#oApi
5789.
     */
5790.
    function _fnGetWidestNode( settings, colIdx )
5791.
    {
5792.
        var idx = _fnGetMaxLenString( settings, colIdx );
5793.
        if ( idx < 0 ) {
5794.
            return null;
5795.
        }
5796.
    
5797.
        var data = settings.aoData[ idx ];
5798.
        return ! data.nTr ? // Might not have been created when deferred rendering
5799.
            $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
5800.
            data.anCells[ colIdx ];
5801.
    }
5802.
    
5803.
    
5804.
    /**
5805.
     * Get the maximum strlen for each data column
5806.
     *  @param {object} settings dataTables settings object
5807.
     *  @param {int} colIdx column of interest
5808.
     *  @returns {string} max string length for each column
5809.
     *  @memberof DataTable#oApi
5810.
     */
5811.
    function _fnGetMaxLenString( settings, colIdx )
5812.
    {
5813.
        var s, max=-1, maxIdx = -1;
5814.
    
5815.
        for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
5816.
            s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
5817.
            s = s.replace( __re_html_remove, '' );
5818.
            s = s.replace( /&nbsp;/g, ' ' );
5819.
    
5820.
            if ( s.length > max ) {
5821.
                max = s.length;
5822.
                maxIdx = i;
5823.
            }
5824.
        }
5825.
    
5826.
        return maxIdx;
5827.
    }
5828.
    
5829.
    
5830.
    /**
5831.
     * Append a CSS unit (only if required) to a string
5832.
     *  @param {string} value to css-ify
5833.
     *  @returns {string} value with css unit
5834.
     *  @memberof DataTable#oApi
5835.
     */
5836.
    function _fnStringToCss( s )
5837.
    {
5838.
        if ( s === null ) {
5839.
            return '0px';
5840.
        }
5841.
    
5842.
        if ( typeof s == 'number' ) {
5843.
            return s < 0 ?
5844.
                '0px' :
5845.
                s+'px';
5846.
        }
5847.
    
5848.
        // Check it has a unit character already
5849.
        return s.match(/\d$/) ?
5850.
            s+'px' :
5851.
            s;
5852.
    }
5853.
    
5854.
    
5855.
    
5856.
    function _fnSortFlatten ( settings )
5857.
    {
5858.
        var
5859.
            i, iLen, k, kLen,
5860.
            aSort = [],
5861.
            aiOrig = [],
5862.
            aoColumns = settings.aoColumns,
5863.
            aDataSort, iCol, sType, srcCol,
5864.
            fixed = settings.aaSortingFixed,
5865.
            fixedObj = $.isPlainObject( fixed ),
5866.
            nestedSort = [],
5867.
            add = function ( a ) {
5868.
                if ( a.length && ! $.isArray( a[0] ) ) {
5869.
                    // 1D array
5870.
                    nestedSort.push( a );
5871.
                }
5872.
                else {
5873.
                    // 2D array
5874.
                    $.merge( nestedSort, a );
5875.
                }
5876.
            };
5877.
    
5878.
        // Build the sort array, with pre-fix and post-fix options if they have been
5879.
        // specified
5880.
        if ( $.isArray( fixed ) ) {
5881.
            add( fixed );
5882.
        }
5883.
    
5884.
        if ( fixedObj && fixed.pre ) {
5885.
            add( fixed.pre );
5886.
        }
5887.
    
5888.
        add( settings.aaSorting );
5889.
    
5890.
        if (fixedObj && fixed.post ) {
5891.
            add( fixed.post );
5892.
        }
5893.
    
5894.
        for ( i=0 ; i<nestedSort.length ; i++ )
5895.
        {
5896.
            srcCol = nestedSort[i][0];
5897.
            aDataSort = aoColumns[ srcCol ].aDataSort;
5898.
    
5899.
            for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
5900.
            {
5901.
                iCol = aDataSort[k];
5902.
                sType = aoColumns[ iCol ].sType || 'string';
5903.
    
5904.
                if ( nestedSort[i]._idx === undefined ) {
5905.
                    nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
5906.
                }
5907.
    
5908.
                aSort.push( {
5909.
                    src:       srcCol,
5910.
                    col:       iCol,
5911.
                    dir:       nestedSort[i][1],
5912.
                    index:     nestedSort[i]._idx,
5913.
                    type:      sType,
5914.
                    formatter: DataTable.ext.type.order[ sType+"-pre" ]
5915.
                } );
5916.
            }
5917.
        }
5918.
    
5919.
        return aSort;
5920.
    }
5921.
    
5922.
    /**
5923.
     * Change the order of the table
5924.
     *  @param {object} oSettings dataTables settings object
5925.
     *  @memberof DataTable#oApi
5926.
     *  @todo This really needs split up!
5927.
     */
5928.
    function _fnSort ( oSettings )
5929.
    {
5930.
        var
5931.
            i, ien, iLen, j, jLen, k, kLen,
5932.
            sDataType, nTh,
5933.
            aiOrig = [],
5934.
            oExtSort = DataTable.ext.type.order,
5935.
            aoData = oSettings.aoData,
5936.
            aoColumns = oSettings.aoColumns,
5937.
            aDataSort, data, iCol, sType, oSort,
5938.
            formatters = 0,
5939.
            sortCol,
5940.
            displayMaster = oSettings.aiDisplayMaster,
5941.
            aSort;
5942.
    
5943.
        // Resolve any column types that are unknown due to addition or invalidation
5944.
        // @todo Can this be moved into a 'data-ready' handler which is called when
5945.
        //   data is going to be used in the table?
5946.
        _fnColumnTypes( oSettings );
5947.
    
5948.
        aSort = _fnSortFlatten( oSettings );
5949.
    
5950.
        for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
5951.
            sortCol = aSort[i];
5952.
    
5953.
            // Track if we can use the fast sort algorithm
5954.
            if ( sortCol.formatter ) {
5955.
                formatters++;
5956.
            }
5957.
    
5958.
            // Load the data needed for the sort, for each cell
5959.
            _fnSortData( oSettings, sortCol.col );
5960.
        }
5961.
    
5962.
        /* No sorting required if server-side or no sorting array */
5963.
        if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
5964.
        {
5965.
            // Create a value - key array of the current row positions such that we can use their
5966.
            // current position during the sort, if values match, in order to perform stable sorting
5967.
            for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
5968.
                aiOrig[ displayMaster[i] ] = i;
5969.
            }
5970.
    
5971.
            /* Do the sort - here we want multi-column sorting based on a given data source (column)
5972.
             * and sorting function (from oSort) in a certain direction. It's reasonably complex to
5973.
             * follow on it's own, but this is what we want (example two column sorting):
5974.
             *  fnLocalSorting = function(a,b){
5975.
             *    var iTest;
5976.
             *    iTest = oSort['string-asc']('data11', 'data12');
5977.
             *      if (iTest !== 0)
5978.
             *        return iTest;
5979.
             *    iTest = oSort['numeric-desc']('data21', 'data22');
5980.
             *    if (iTest !== 0)
5981.
             *      return iTest;
5982.
             *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
5983.
             *  }
5984.
             * Basically we have a test for each sorting column, if the data in that column is equal,
5985.
             * test the next column. If all columns match, then we use a numeric sort on the row
5986.
             * positions in the original data array to provide a stable sort.
5987.
             *
5988.
             * Note - I know it seems excessive to have two sorting methods, but the first is around
5989.
             * 15% faster, so the second is only maintained for backwards compatibility with sorting
5990.
             * methods which do not have a pre-sort formatting function.
5991.
             */
5992.
            if ( formatters === aSort.length ) {
5993.
                // All sort types have formatting functions
5994.
                displayMaster.sort( function ( a, b ) {
5995.
                    var
5996.
                        x, y, k, test, sort,
5997.
                        len=aSort.length,
5998.
                        dataA = aoData[a]._aSortData,
5999.
                        dataB = aoData[b]._aSortData;
6000.
    
6001.
                    for ( k=0 ; k<len ; k++ ) {
6002.
                        sort = aSort[k];
6003.
    
6004.
                        x = dataA[ sort.col ];
6005.
                        y = dataB[ sort.col ];
6006.
    
6007.
                        test = x<y ? -1 : x>y ? 1 : 0;
6008.
                        if ( test !== 0 ) {
6009.
                            return sort.dir === 'asc' ? test : -test;
6010.
                        }
6011.
                    }
6012.
    
6013.
                    x = aiOrig[a];
6014.
                    y = aiOrig[b];
6015.
                    return x<y ? -1 : x>y ? 1 : 0;
6016.
                } );
6017.
            }
6018.
            else {
6019.
                // Depreciated - remove in 1.11 (providing a plug-in option)
6020.
                // Not all sort types have formatting methods, so we have to call their sorting
6021.
                // methods.
6022.
                displayMaster.sort( function ( a, b ) {
6023.
                    var
6024.
                        x, y, k, l, test, sort, fn,
6025.
                        len=aSort.length,
6026.
                        dataA = aoData[a]._aSortData,
6027.
                        dataB = aoData[b]._aSortData;
6028.
    
6029.
                    for ( k=0 ; k<len ; k++ ) {
6030.
                        sort = aSort[k];
6031.
    
6032.
                        x = dataA[ sort.col ];
6033.
                        y = dataB[ sort.col ];
6034.
    
6035.
                        fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
6036.
                        test = fn( x, y );
6037.
                        if ( test !== 0 ) {
6038.
                            return test;
6039.
                        }
6040.
                    }
6041.
    
6042.
                    x = aiOrig[a];
6043.
                    y = aiOrig[b];
6044.
                    return x<y ? -1 : x>y ? 1 : 0;
6045.
                } );
6046.
            }
6047.
        }
6048.
    
6049.
        /* Tell the draw function that we have sorted the data */
6050.
        oSettings.bSorted = true;
6051.
    }
6052.
    
6053.
    
6054.
    function _fnSortAria ( settings )
6055.
    {
6056.
        var label;
6057.
        var nextSort;
6058.
        var columns = settings.aoColumns;
6059.
        var aSort = _fnSortFlatten( settings );
6060.
        var oAria = settings.oLanguage.oAria;
6061.
    
6062.
        // ARIA attributes - need to loop all columns, to update all (removing old
6063.
        // attributes as needed)
6064.
        for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
6065.
        {
6066.
            var col = columns[i];
6067.
            var asSorting = col.asSorting;
6068.
            var sTitle = col.sTitle.replace( /<.*?>/g, "" );
6069.
            var th = col.nTh;
6070.
    
6071.
            // IE7 is throwing an error when setting these properties with jQuery's
6072.
            // attr() and removeAttr() methods...
6073.
            th.removeAttribute('aria-sort');
6074.
    
6075.
            /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
6076.
            if ( col.bSortable ) {
6077.
                if ( aSort.length > 0 && aSort[0].col == i ) {
6078.
                    th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
6079.
                    nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
6080.
                }
6081.
                else {
6082.
                    nextSort = asSorting[0];
6083.
                }
6084.
    
6085.
                label = sTitle + ( nextSort === "asc" ?
6086.
                    oAria.sSortAscending :
6087.
                    oAria.sSortDescending
6088.
                );
6089.
            }
6090.
            else {
6091.
                label = sTitle;
6092.
            }
6093.
    
6094.
            th.setAttribute('aria-label', label);
6095.
        }
6096.
    }
6097.
    
6098.
    
6099.
    /**
6100.
     * Function to run on user sort request
6101.
     *  @param {object} settings dataTables settings object
6102.
     *  @param {node} attachTo node to attach the handler to
6103.
     *  @param {int} colIdx column sorting index
6104.
     *  @param {boolean} [append=false] Append the requested sort to the existing
6105.
     *    sort if true (i.e. multi-column sort)
6106.
     *  @param {function} [callback] callback function
6107.
     *  @memberof DataTable#oApi
6108.
     */
6109.
    function _fnSortListener ( settings, colIdx, append, callback )
6110.
    {
6111.
        var col = settings.aoColumns[ colIdx ];
6112.
        var sorting = settings.aaSorting;
6113.
        var asSorting = col.asSorting;
6114.
        var nextSortIdx;
6115.
        var next = function ( a, overflow ) {
6116.
            var idx = a._idx;
6117.
            if ( idx === undefined ) {
6118.
                idx = $.inArray( a[1], asSorting );
6119.
            }
6120.
    
6121.
            return idx+1 < asSorting.length ?
6122.
                idx+1 :
6123.
                overflow ?
6124.
                    null :
6125.
                    0;
6126.
        };
6127.
    
6128.
        // Convert to 2D array if needed
6129.
        if ( typeof sorting[0] === 'number' ) {
6130.
            sorting = settings.aaSorting = [ sorting ];
6131.
        }
6132.
    
6133.
        // If appending the sort then we are multi-column sorting
6134.
        if ( append && settings.oFeatures.bSortMulti ) {
6135.
            // Are we already doing some kind of sort on this column?
6136.
            var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
6137.
    
6138.
            if ( sortIdx !== -1 ) {
6139.
                // Yes, modify the sort
6140.
                nextSortIdx = next( sorting[sortIdx], true );
6141.
    
6142.
                if ( nextSortIdx === null && sorting.length === 1 ) {
6143.
                    nextSortIdx = 0; // can't remove sorting completely
6144.
                }
6145.
    
6146.
                if ( nextSortIdx === null ) {
6147.
                    sorting.splice( sortIdx, 1 );
6148.
                }
6149.
                else {
6150.
                    sorting[sortIdx][1] = asSorting[ nextSortIdx ];
6151.
                    sorting[sortIdx]._idx = nextSortIdx;
6152.
                }
6153.
            }
6154.
            else {
6155.
                // No sort on this column yet
6156.
                sorting.push( [ colIdx, asSorting[0], 0 ] );
6157.
                sorting[sorting.length-1]._idx = 0;
6158.
            }
6159.
        }
6160.
        else if ( sorting.length && sorting[0][0] == colIdx ) {
6161.
            // Single column - already sorting on this column, modify the sort
6162.
            nextSortIdx = next( sorting[0] );
6163.
    
6164.
            sorting.length = 1;
6165.
            sorting[0][1] = asSorting[ nextSortIdx ];
6166.
            sorting[0]._idx = nextSortIdx;
6167.
        }
6168.
        else {
6169.
            // Single column - sort only on this column
6170.
            sorting.length = 0;
6171.
            sorting.push( [ colIdx, asSorting[0] ] );
6172.
            sorting[0]._idx = 0;
6173.
        }
6174.
    
6175.
        // Run the sort by calling a full redraw
6176.
        _fnReDraw( settings );
6177.
    
6178.
        // callback used for async user interaction
6179.
        if ( typeof callback == 'function' ) {
6180.
            callback( settings );
6181.
        }
6182.
    }
6183.
    
6184.
    
6185.
    /**
6186.
     * Attach a sort handler (click) to a node
6187.
     *  @param {object} settings dataTables settings object
6188.
     *  @param {node} attachTo node to attach the handler to
6189.
     *  @param {int} colIdx column sorting index
6190.
     *  @param {function} [callback] callback function
6191.
     *  @memberof DataTable#oApi
6192.
     */
6193.
    function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
6194.
    {
6195.
        var col = settings.aoColumns[ colIdx ];
6196.
    
6197.
        _fnBindAction( attachTo, {}, function (e) {
6198.
            /* If the column is not sortable - don't to anything */
6199.
            if ( col.bSortable === false ) {
6200.
                return;
6201.
            }
6202.
    
6203.
            // If processing is enabled use a timeout to allow the processing
6204.
            // display to be shown - otherwise to it synchronously
6205.
            if ( settings.oFeatures.bProcessing ) {
6206.
                _fnProcessingDisplay( settings, true );
6207.
    
6208.
                setTimeout( function() {
6209.
                    _fnSortListener( settings, colIdx, e.shiftKey, callback );
6210.
    
6211.
                    // In server-side processing, the draw callback will remove the
6212.
                    // processing display
6213.
                    if ( _fnDataSource( settings ) !== 'ssp' ) {
6214.
                        _fnProcessingDisplay( settings, false );
6215.
                    }
6216.
                }, 0 );
6217.
            }
6218.
            else {
6219.
                _fnSortListener( settings, colIdx, e.shiftKey, callback );
6220.
            }
6221.
        } );
6222.
    }
6223.
    
6224.
    
6225.
    /**
6226.
     * Set the sorting classes on table's body, Note: it is safe to call this function
6227.
     * when bSort and bSortClasses are false
6228.
     *  @param {object} oSettings dataTables settings object
6229.
     *  @memberof DataTable#oApi
6230.
     */
6231.
    function _fnSortingClasses( settings )
6232.
    {
6233.
        var oldSort = settings.aLastSort;
6234.
        var sortClass = settings.oClasses.sSortColumn;
6235.
        var sort = _fnSortFlatten( settings );
6236.
        var features = settings.oFeatures;
6237.
        var i, ien, colIdx;
6238.
    
6239.
        if ( features.bSort && features.bSortClasses ) {
6240.
            // Remove old sorting classes
6241.
            for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
6242.
                colIdx = oldSort[i].src;
6243.
    
6244.
                // Remove column sorting
6245.
                $( _pluck( settings.aoData, 'anCells', colIdx ) )
6246.
                    .removeClass( sortClass + (i<2 ? i+1 : 3) );
6247.
            }
6248.
    
6249.
            // Add new column sorting
6250.
            for ( i=0, ien=sort.length ; i<ien ; i++ ) {
6251.
                colIdx = sort[i].src;
6252.
    
6253.
                $( _pluck( settings.aoData, 'anCells', colIdx ) )
6254.
                    .addClass( sortClass + (i<2 ? i+1 : 3) );
6255.
            }
6256.
        }
6257.
    
6258.
        settings.aLastSort = sort;
6259.
    }
6260.
    
6261.
    
6262.
    // Get the data to sort a column, be it from cache, fresh (populating the
6263.
    // cache), or from a sort formatter
6264.
    function _fnSortData( settings, idx )
6265.
    {
6266.
        // Custom sorting function - provided by the sort data type
6267.
        var column = settings.aoColumns[ idx ];
6268.
        var customSort = DataTable.ext.order[ column.sSortDataType ];
6269.
        var customData;
6270.
    
6271.
        if ( customSort ) {
6272.
            customData = customSort.call( settings.oInstance, settings, idx,
6273.
                _fnColumnIndexToVisible( settings, idx )
6274.
            );
6275.
        }
6276.
    
6277.
        // Use / populate cache
6278.
        var row, cellData;
6279.
        var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
6280.
    
6281.
        for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
6282.
            row = settings.aoData[i];
6283.
    
6284.
            if ( ! row._aSortData ) {
6285.
                row._aSortData = [];
6286.
            }
6287.
    
6288.
            if ( ! row._aSortData[idx] || customSort ) {
6289.
                cellData = customSort ?
6290.
                    customData[i] : // If there was a custom sort function, use data from there
6291.
                    _fnGetCellData( settings, i, idx, 'sort' );
6292.
    
6293.
                row._aSortData[ idx ] = formatter ?
6294.
                    formatter( cellData ) :
6295.
                    cellData;
6296.
            }
6297.
        }
6298.
    }
6299.
    
6300.
    
6301.
    
6302.
    /**
6303.
     * Save the state of a table
6304.
     *  @param {object} oSettings dataTables settings object
6305.
     *  @memberof DataTable#oApi
6306.
     */
6307.
    function _fnSaveState ( settings )
6308.
    {
6309.
        if ( !settings.oFeatures.bStateSave || settings.bDestroying )
6310.
        {
6311.
            return;
6312.
        }
6313.
    
6314.
        /* Store the interesting variables */
6315.
        var state = {
6316.
            time:    +new Date(),
6317.
            start:   settings._iDisplayStart,
6318.
            length:  settings._iDisplayLength,
6319.
            order:   $.extend( true, [], settings.aaSorting ),
6320.
            search:  _fnSearchToCamel( settings.oPreviousSearch ),
6321.
            columns: $.map( settings.aoColumns, function ( col, i ) {
6322.
                return {
6323.
                    visible: col.bVisible,
6324.
                    search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
6325.
                };
6326.
            } )
6327.
        };
6328.
    
6329.
        _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
6330.
    
6331.
        settings.oSavedState = state;
6332.
        settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
6333.
    }
6334.
    
6335.
    
6336.
    /**
6337.
     * Attempt to load a saved table state
6338.
     *  @param {object} oSettings dataTables settings object
6339.
     *  @param {object} oInit DataTables init object so we can override settings
6340.
     *  @param {function} callback Callback to execute when the state has been loaded
6341.
     *  @memberof DataTable#oApi
6342.
     */
6343.
    function _fnLoadState ( settings, oInit, callback )
6344.
    {
6345.
        var i, ien;
6346.
        var columns = settings.aoColumns;
6347.
        var loaded = function ( s ) {
6348.
            if ( ! s || ! s.time ) {
6349.
                callback();
6350.
                return;
6351.
            }
6352.
    
6353.
            // Allow custom and plug-in manipulation functions to alter the saved data set and
6354.
            // cancelling of loading by returning false
6355.
            var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );
6356.
            if ( $.inArray( false, abStateLoad ) !== -1 ) {
6357.
                callback();
6358.
                return;
6359.
            }
6360.
    
6361.
            // Reject old data
6362.
            var duration = settings.iStateDuration;
6363.
            if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
6364.
                callback();
6365.
                return;
6366.
            }
6367.
    
6368.
            // Number of columns have changed - all bets are off, no restore of settings
6369.
            if ( s.columns && columns.length !== s.columns.length ) {
6370.
                callback();
6371.
                return;
6372.
            }
6373.
    
6374.
            // Store the saved state so it might be accessed at any time
6375.
            settings.oLoadedState = $.extend( true, {}, s );
6376.
    
6377.
            // Restore key features - todo - for 1.11 this needs to be done by
6378.
            // subscribed events
6379.
            if ( s.start !== undefined ) {
6380.
                settings._iDisplayStart    = s.start;
6381.
                settings.iInitDisplayStart = s.start;
6382.
            }
6383.
            if ( s.length !== undefined ) {
6384.
                settings._iDisplayLength   = s.length;
6385.
            }
6386.
    
6387.
            // Order
6388.
            if ( s.order !== undefined ) {
6389.
                settings.aaSorting = [];
6390.
                $.each( s.order, function ( i, col ) {
6391.
                    settings.aaSorting.push( col[0] >= columns.length ?
6392.
                        [ 0, col[1] ] :
6393.
                        col
6394.
                    );
6395.
                } );
6396.
            }
6397.
    
6398.
            // Search
6399.
            if ( s.search !== undefined ) {
6400.
                $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
6401.
            }
6402.
    
6403.
            // Columns
6404.
            //
6405.
            if ( s.columns ) {
6406.
                for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
6407.
                    var col = s.columns[i];
6408.
    
6409.
                    // Visibility
6410.
                    if ( col.visible !== undefined ) {
6411.
                        columns[i].bVisible = col.visible;
6412.
                    }
6413.
    
6414.
                    // Search
6415.
                    if ( col.search !== undefined ) {
6416.
                        $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
6417.
                    }
6418.
                }
6419.
            }
6420.
    
6421.
            _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
6422.
            callback();
6423.
        };
6424.
    
6425.
        if ( ! settings.oFeatures.bStateSave ) {
6426.
            callback();
6427.
            return;
6428.
        }
6429.
    
6430.
        var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
6431.
    
6432.
        if ( state !== undefined ) {
6433.
            loaded( state );
6434.
        }
6435.
        // otherwise, wait for the loaded callback to be executed
6436.
    }
6437.
    
6438.
    
6439.
    /**
6440.
     * Return the settings object for a particular table
6441.
     *  @param {node} table table we are using as a dataTable
6442.
     *  @returns {object} Settings object - or null if not found
6443.
     *  @memberof DataTable#oApi
6444.
     */
6445.
    function _fnSettingsFromNode ( table )
6446.
    {
6447.
        var settings = DataTable.settings;
6448.
        var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
6449.
    
6450.
        return idx !== -1 ?
6451.
            settings[ idx ] :
6452.
            null;
6453.
    }
6454.
    
6455.
    
6456.
    /**
6457.
     * Log an error message
6458.
     *  @param {object} settings dataTables settings object
6459.
     *  @param {int} level log error messages, or display them to the user
6460.
     *  @param {string} msg error message
6461.
     *  @param {int} tn Technical note id to get more information about the error.
6462.
     *  @memberof DataTable#oApi
6463.
     */
6464.
    function _fnLog( settings, level, msg, tn )
6465.
    {
6466.
        msg = 'DataTables warning: '+
6467.
            (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
6468.
    
6469.
        if ( tn ) {
6470.
            msg += '. For more information about this error, please see '+
6471.
            'http://datatables.net/tn/'+tn;
6472.
        }
6473.
    
6474.
        if ( ! level  ) {
6475.
            // Backwards compatibility pre 1.10
6476.
            var ext = DataTable.ext;
6477.
            var type = ext.sErrMode || ext.errMode;
6478.
    
6479.
            if ( settings ) {
6480.
                _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
6481.
            }
6482.
    
6483.
            if ( type == 'alert' ) {
6484.
                alert( msg );
6485.
            }
6486.
            else if ( type == 'throw' ) {
6487.
                throw new Error(msg);
6488.
            }
6489.
            else if ( typeof type == 'function' ) {
6490.
                type( settings, tn, msg );
6491.
            }
6492.
        }
6493.
        else if ( window.console && console.log ) {
6494.
            console.log( msg );
6495.
        }
6496.
    }
6497.
    
6498.
    
6499.
    /**
6500.
     * See if a property is defined on one object, if so assign it to the other object
6501.
     *  @param {object} ret target object
6502.
     *  @param {object} src source object
6503.
     *  @param {string} name property
6504.
     *  @param {string} [mappedName] name to map too - optional, name used if not given
6505.
     *  @memberof DataTable#oApi
6506.
     */
6507.
    function _fnMap( ret, src, name, mappedName )
6508.
    {
6509.
        if ( $.isArray( name ) ) {
6510.
            $.each( name, function (i, val) {
6511.
                if ( $.isArray( val ) ) {
6512.
                    _fnMap( ret, src, val[0], val[1] );
6513.
                }
6514.
                else {
6515.
                    _fnMap( ret, src, val );
6516.
                }
6517.
            } );
6518.
    
6519.
            return;
6520.
        }
6521.
    
6522.
        if ( mappedName === undefined ) {
6523.
            mappedName = name;
6524.
        }
6525.
    
6526.
        if ( src[name] !== undefined ) {
6527.
            ret[mappedName] = src[name];
6528.
        }
6529.
    }
6530.
    
6531.
    
6532.
    /**
6533.
     * Extend objects - very similar to jQuery.extend, but deep copy objects, and
6534.
     * shallow copy arrays. The reason we need to do this, is that we don't want to
6535.
     * deep copy array init values (such as aaSorting) since the dev wouldn't be
6536.
     * able to override them, but we do want to deep copy arrays.
6537.
     *  @param {object} out Object to extend
6538.
     *  @param {object} extender Object from which the properties will be applied to
6539.
     *      out
6540.
     *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
6541.
     *      independent copy with the exception of the `data` or `aaData` parameters
6542.
     *      if they are present. This is so you can pass in a collection to
6543.
     *      DataTables and have that used as your data source without breaking the
6544.
     *      references
6545.
     *  @returns {object} out Reference, just for convenience - out === the return.
6546.
     *  @memberof DataTable#oApi
6547.
     *  @todo This doesn't take account of arrays inside the deep copied objects.
6548.
     */
6549.
    function _fnExtend( out, extender, breakRefs )
6550.
    {
6551.
        var val;
6552.
    
6553.
        for ( var prop in extender ) {
6554.
            if ( extender.hasOwnProperty(prop) ) {
6555.
                val = extender[prop];
6556.
    
6557.
                if ( $.isPlainObject( val ) ) {
6558.
                    if ( ! $.isPlainObject( out[prop] ) ) {
6559.
                        out[prop] = {};
6560.
                    }
6561.
                    $.extend( true, out[prop], val );
6562.
                }
6563.
                else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
6564.
                    out[prop] = val.slice();
6565.
                }
6566.
                else {
6567.
                    out[prop] = val;
6568.
                }
6569.
            }
6570.
        }
6571.
    
6572.
        return out;
6573.
    }
6574.
    
6575.
    
6576.
    /**
6577.
     * Bind an event handers to allow a click or return key to activate the callback.
6578.
     * This is good for accessibility since a return on the keyboard will have the
6579.
     * same effect as a click, if the element has focus.
6580.
     *  @param {element} n Element to bind the action to
6581.
     *  @param {object} oData Data object to pass to the triggered function
6582.
     *  @param {function} fn Callback function for when the event is triggered
6583.
     *  @memberof DataTable#oApi
6584.
     */
6585.
    function _fnBindAction( n, oData, fn )
6586.
    {
6587.
        $(n)
6588.
            .on( 'click.DT', oData, function (e) {
6589.
                    $(n).trigger('blur'); // Remove focus outline for mouse users
6590.
                    fn(e);
6591.
                } )
6592.
            .on( 'keypress.DT', oData, function (e){
6593.
                    if ( e.which === 13 ) {
6594.
                        e.preventDefault();
6595.
                        fn(e);
6596.
                    }
6597.
                } )
6598.
            .on( 'selectstart.DT', function () {
6599.
                    /* Take the brutal approach to cancelling text selection */
6600.
                    return false;
6601.
                } );
6602.
    }
6603.
    
6604.
    
6605.
    /**
6606.
     * Register a callback function. Easily allows a callback function to be added to
6607.
     * an array store of callback functions that can then all be called together.
6608.
     *  @param {object} oSettings dataTables settings object
6609.
     *  @param {string} sStore Name of the array storage for the callbacks in oSettings
6610.
     *  @param {function} fn Function to be called back
6611.
     *  @param {string} sName Identifying name for the callback (i.e. a label)
6612.
     *  @memberof DataTable#oApi
6613.
     */
6614.
    function _fnCallbackReg( oSettings, sStore, fn, sName )
6615.
    {
6616.
        if ( fn )
6617.
        {
6618.
            oSettings[sStore].push( {
6619.
                "fn": fn,
6620.
                "sName": sName
6621.
            } );
6622.
        }
6623.
    }
6624.
    
6625.
    
6626.
    /**
6627.
     * Fire callback functions and trigger events. Note that the loop over the
6628.
     * callback array store is done backwards! Further note that you do not want to
6629.
     * fire off triggers in time sensitive applications (for example cell creation)
6630.
     * as its slow.
6631.
     *  @param {object} settings dataTables settings object
6632.
     *  @param {string} callbackArr Name of the array storage for the callbacks in
6633.
     *      oSettings
6634.
     *  @param {string} eventName Name of the jQuery custom event to trigger. If
6635.
     *      null no trigger is fired
6636.
     *  @param {array} args Array of arguments to pass to the callback function /
6637.
     *      trigger
6638.
     *  @memberof DataTable#oApi
6639.
     */
6640.
    function _fnCallbackFire( settings, callbackArr, eventName, args )
6641.
    {
6642.
        var ret = [];
6643.
    
6644.
        if ( callbackArr ) {
6645.
            ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
6646.
                return val.fn.apply( settings.oInstance, args );
6647.
            } );
6648.
        }
6649.
    
6650.
        if ( eventName !== null ) {
6651.
            var e = $.Event( eventName+'.dt' );
6652.
    
6653.
            $(settings.nTable).trigger( e, args );
6654.
    
6655.
            ret.push( e.result );
6656.
        }
6657.
    
6658.
        return ret;
6659.
    }
6660.
    
6661.
    
6662.
    function _fnLengthOverflow ( settings )
6663.
    {
6664.
        var
6665.
            start = settings._iDisplayStart,
6666.
            end = settings.fnDisplayEnd(),
6667.
            len = settings._iDisplayLength;
6668.
    
6669.
        /* If we have space to show extra rows (backing up from the end point - then do so */
6670.
        if ( start >= end )
6671.
        {
6672.
            start = end - len;
6673.
        }
6674.
    
6675.
        // Keep the start record on the current page
6676.
        start -= (start % len);
6677.
    
6678.
        if ( len === -1 || start < 0 )
6679.
        {
6680.
            start = 0;
6681.
        }
6682.
    
6683.
        settings._iDisplayStart = start;
6684.
    }
6685.
    
6686.
    
6687.
    function _fnRenderer( settings, type )
6688.
    {
6689.
        var renderer = settings.renderer;
6690.
        var host = DataTable.ext.renderer[type];
6691.
    
6692.
        if ( $.isPlainObject( renderer ) && renderer[type] ) {
6693.
            // Specific renderer for this type. If available use it, otherwise use
6694.
            // the default.
6695.
            return host[renderer[type]] || host._;
6696.
        }
6697.
        else if ( typeof renderer === 'string' ) {
6698.
            // Common renderer - if there is one available for this type use it,
6699.
            // otherwise use the default
6700.
            return host[renderer] || host._;
6701.
        }
6702.
    
6703.
        // Use the default
6704.
        return host._;
6705.
    }
6706.
    
6707.
    
6708.
    /**
6709.
     * Detect the data source being used for the table. Used to simplify the code
6710.
     * a little (ajax) and to make it compress a little smaller.
6711.
     *
6712.
     *  @param {object} settings dataTables settings object
6713.
     *  @returns {string} Data source
6714.
     *  @memberof DataTable#oApi
6715.
     */
6716.
    function _fnDataSource ( settings )
6717.
    {
6718.
        if ( settings.oFeatures.bServerSide ) {
6719.
            return 'ssp';
6720.
        }
6721.
        else if ( settings.ajax || settings.sAjaxSource ) {
6722.
            return 'ajax';
6723.
        }
6724.
        return 'dom';
6725.
    }
6726.
    
6727.
 
6728.
    
6729.
    
6730.
    /**
6731.
     * Computed structure of the DataTables API, defined by the options passed to
6732.
     * `DataTable.Api.register()` when building the API.
6733.
     *
6734.
     * The structure is built in order to speed creation and extension of the Api
6735.
     * objects since the extensions are effectively pre-parsed.
6736.
     *
6737.
     * The array is an array of objects with the following structure, where this
6738.
     * base array represents the Api prototype base:
6739.
     *
6740.
     *     [
6741.
     *       {
6742.
     *         name:      'data'                -- string   - Property name
6743.
     *         val:       function () {},       -- function - Api method (or undefined if just an object
6744.
     *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
6745.
     *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
6746.
     *       },
6747.
     *       {
6748.
     *         name:     'row'
6749.
     *         val:       {},
6750.
     *         methodExt: [ ... ],
6751.
     *         propExt:   [
6752.
     *           {
6753.
     *             name:      'data'
6754.
     *             val:       function () {},
6755.
     *             methodExt: [ ... ],
6756.
     *             propExt:   [ ... ]
6757.
     *           },
6758.
     *           ...
6759.
     *         ]
6760.
     *       }
6761.
     *     ]
6762.
     *
6763.
     * @type {Array}
6764.
     * @ignore
6765.
     */
6766.
    var __apiStruct = [];
6767.
    
6768.
    
6769.
    /**
6770.
     * `Array.prototype` reference.
6771.
     *
6772.
     * @type object
6773.
     * @ignore
6774.
     */
6775.
    var __arrayProto = Array.prototype;
6776.
    
6777.
    
6778.
    /**
6779.
     * Abstraction for `context` parameter of the `Api` constructor to allow it to
6780.
     * take several different forms for ease of use.
6781.
     *
6782.
     * Each of the input parameter types will be converted to a DataTables settings
6783.
     * object where possible.
6784.
     *
6785.
     * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
6786.
     *   of:
6787.
     *
6788.
     *   * `string` - jQuery selector. Any DataTables' matching the given selector
6789.
     *     with be found and used.
6790.
     *   * `node` - `TABLE` node which has already been formed into a DataTable.
6791.
     *   * `jQuery` - A jQuery object of `TABLE` nodes.
6792.
     *   * `object` - DataTables settings object
6793.
     *   * `DataTables.Api` - API instance
6794.
     * @return {array|null} Matching DataTables settings objects. `null` or
6795.
     *   `undefined` is returned if no matching DataTable is found.
6796.
     * @ignore
6797.
     */
6798.
    var _toSettings = function ( mixed )
6799.
    {
6800.
        var idx, jq;
6801.
        var settings = DataTable.settings;
6802.
        var tables = $.map( settings, function (el, i) {
6803.
            return el.nTable;
6804.
        } );
6805.
    
6806.
        if ( ! mixed ) {
6807.
            return [];
6808.
        }
6809.
        else if ( mixed.nTable && mixed.oApi ) {
6810.
            // DataTables settings object
6811.
            return [ mixed ];
6812.
        }
6813.
        else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6814.
            // Table node
6815.
            idx = $.inArray( mixed, tables );
6816.
            return idx !== -1 ? [ settings[idx] ] : null;
6817.
        }
6818.
        else if ( mixed && typeof mixed.settings === 'function' ) {
6819.
            return mixed.settings().toArray();
6820.
        }
6821.
        else if ( typeof mixed === 'string' ) {
6822.
            // jQuery selector
6823.
            jq = $(mixed);
6824.
        }
6825.
        else if ( mixed instanceof $ ) {
6826.
            // jQuery object (also DataTables instance)
6827.
            jq = mixed;
6828.
        }
6829.
    
6830.
        if ( jq ) {
6831.
            return jq.map( function(i) {
6832.
                idx = $.inArray( this, tables );
6833.
                return idx !== -1 ? settings[idx] : null;
6834.
            } ).toArray();
6835.
        }
6836.
    };
6837.
    
6838.
    
6839.
    /**
6840.
     * DataTables API class - used to control and interface with  one or more
6841.
     * DataTables enhanced tables.
6842.
     *
6843.
     * The API class is heavily based on jQuery, presenting a chainable interface
6844.
     * that you can use to interact with tables. Each instance of the API class has
6845.
     * a "context" - i.e. the tables that it will operate on. This could be a single
6846.
     * table, all tables on a page or a sub-set thereof.
6847.
     *
6848.
     * Additionally the API is designed to allow you to easily work with the data in
6849.
     * the tables, retrieving and manipulating it as required. This is done by
6850.
     * presenting the API class as an array like interface. The contents of the
6851.
     * array depend upon the actions requested by each method (for example
6852.
     * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6853.
     * return an array of objects or arrays depending upon your table's
6854.
     * configuration). The API object has a number of array like methods (`push`,
6855.
     * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6856.
     * `unique` etc) to assist your working with the data held in a table.
6857.
     *
6858.
     * Most methods (those which return an Api instance) are chainable, which means
6859.
     * the return from a method call also has all of the methods available that the
6860.
     * top level object had. For example, these two calls are equivalent:
6861.
     *
6862.
     *     // Not chained
6863.
     *     api.row.add( {...} );
6864.
     *     api.draw();
6865.
     *
6866.
     *     // Chained
6867.
     *     api.row.add( {...} ).draw();
6868.
     *
6869.
     * @class DataTable.Api
6870.
     * @param {array|object|string|jQuery} context DataTable identifier. This is
6871.
     *   used to define which DataTables enhanced tables this API will operate on.
6872.
     *   Can be one of:
6873.
     *
6874.
     *   * `string` - jQuery selector. Any DataTables' matching the given selector
6875.
     *     with be found and used.
6876.
     *   * `node` - `TABLE` node which has already been formed into a DataTable.
6877.
     *   * `jQuery` - A jQuery object of `TABLE` nodes.
6878.
     *   * `object` - DataTables settings object
6879.
     * @param {array} [data] Data to initialise the Api instance with.
6880.
     *
6881.
     * @example
6882.
     *   // Direct initialisation during DataTables construction
6883.
     *   var api = $('#example').DataTable();
6884.
     *
6885.
     * @example
6886.
     *   // Initialisation using a DataTables jQuery object
6887.
     *   var api = $('#example').dataTable().api();
6888.
     *
6889.
     * @example
6890.
     *   // Initialisation as a constructor
6891.
     *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
6892.
     */
6893.
    _Api = function ( context, data )
6894.
    {
6895.
        if ( ! (this instanceof _Api) ) {
6896.
            return new _Api( context, data );
6897.
        }
6898.
    
6899.
        var settings = [];
6900.
        var ctxSettings = function ( o ) {
6901.
            var a = _toSettings( o );
6902.
            if ( a ) {
6903.
                settings.push.apply( settings, a );
6904.
            }
6905.
        };
6906.
    
6907.
        if ( $.isArray( context ) ) {
6908.
            for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6909.
                ctxSettings( context[i] );
6910.
            }
6911.
        }
6912.
        else {
6913.
            ctxSettings( context );
6914.
        }
6915.
    
6916.
        // Remove duplicates
6917.
        this.context = _unique( settings );
6918.
    
6919.
        // Initial data
6920.
        if ( data ) {
6921.
            $.merge( this, data );
6922.
        }
6923.
    
6924.
        // selector
6925.
        this.selector = {
6926.
            rows: null,
6927.
            cols: null,
6928.
            opts: null
6929.
        };
6930.
    
6931.
        _Api.extend( this, this, __apiStruct );
6932.
    };
6933.
    
6934.
    DataTable.Api = _Api;
6935.
    
6936.
    // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6937.
    // isPlainObject.
6938.
    $.extend( _Api.prototype, {
6939.
        any: function ()
6940.
        {
6941.
            return this.count() !== 0;
6942.
        },
6943.
    
6944.
    
6945.
        concat:  __arrayProto.concat,
6946.
    
6947.
    
6948.
        context: [], // array of table settings objects
6949.
    
6950.
    
6951.
        count: function ()
6952.
        {
6953.
            return this.flatten().length;
6954.
        },
6955.
    
6956.
    
6957.
        each: function ( fn )
6958.
        {
6959.
            for ( var i=0, ien=this.length ; i<ien; i++ ) {
6960.
                fn.call( this, this[i], i, this );
6961.
            }
6962.
    
6963.
            return this;
6964.
        },
6965.
    
6966.
    
6967.
        eq: function ( idx )
6968.
        {
6969.
            var ctx = this.context;
6970.
    
6971.
            return ctx.length > idx ?
6972.
                new _Api( ctx[idx], this[idx] ) :
6973.
                null;
6974.
        },
6975.
    
6976.
    
6977.
        filter: function ( fn )
6978.
        {
6979.
            var a = [];
6980.
    
6981.
            if ( __arrayProto.filter ) {
6982.
                a = __arrayProto.filter.call( this, fn, this );
6983.
            }
6984.
            else {
6985.
                // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6986.
                for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6987.
                    if ( fn.call( this, this[i], i, this ) ) {
6988.
                        a.push( this[i] );
6989.
                    }
6990.
                }
6991.
            }
6992.
    
6993.
            return new _Api( this.context, a );
6994.
        },
6995.
    
6996.
    
6997.
        flatten: function ()
6998.
        {
6999.
            var a = [];
7000.
            return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
7001.
        },
7002.
    
7003.
    
7004.
        join:    __arrayProto.join,
7005.
    
7006.
    
7007.
        indexOf: __arrayProto.indexOf || function (obj, start)
7008.
        {
7009.
            for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
7010.
                if ( this[i] === obj ) {
7011.
                    return i;
7012.
                }
7013.
            }
7014.
            return -1;
7015.
        },
7016.
    
7017.
        iterator: function ( flatten, type, fn, alwaysNew ) {
7018.
            var
7019.
                a = [], ret,
7020.
                i, ien, j, jen,
7021.
                context = this.context,
7022.
                rows, items, item,
7023.
                selector = this.selector;
7024.
    
7025.
            // Argument shifting
7026.
            if ( typeof flatten === 'string' ) {
7027.
                alwaysNew = fn;
7028.
                fn = type;
7029.
                type = flatten;
7030.
                flatten = false;
7031.
            }
7032.
    
7033.
            for ( i=0, ien=context.length ; i<ien ; i++ ) {
7034.
                var apiInst = new _Api( context[i] );
7035.
    
7036.
                if ( type === 'table' ) {
7037.
                    ret = fn.call( apiInst, context[i], i );
7038.
    
7039.
                    if ( ret !== undefined ) {
7040.
                        a.push( ret );
7041.
                    }
7042.
                }
7043.
                else if ( type === 'columns' || type === 'rows' ) {
7044.
                    // this has same length as context - one entry for each table
7045.
                    ret = fn.call( apiInst, context[i], this[i], i );
7046.
    
7047.
                    if ( ret !== undefined ) {
7048.
                        a.push( ret );
7049.
                    }
7050.
                }
7051.
                else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
7052.
                    // columns and rows share the same structure.
7053.
                    // 'this' is an array of column indexes for each context
7054.
                    items = this[i];
7055.
    
7056.
                    if ( type === 'column-rows' ) {
7057.
                        rows = _selector_row_indexes( context[i], selector.opts );
7058.
                    }
7059.
    
7060.
                    for ( j=0, jen=items.length ; j<jen ; j++ ) {
7061.
                        item = items[j];
7062.
    
7063.
                        if ( type === 'cell' ) {
7064.
                            ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
7065.
                        }
7066.
                        else {
7067.
                            ret = fn.call( apiInst, context[i], item, i, j, rows );
7068.
                        }
7069.
    
7070.
                        if ( ret !== undefined ) {
7071.
                            a.push( ret );
7072.
                        }
7073.
                    }
7074.
                }
7075.
            }
7076.
    
7077.
            if ( a.length || alwaysNew ) {
7078.
                var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
7079.
                var apiSelector = api.selector;
7080.
                apiSelector.rows = selector.rows;
7081.
                apiSelector.cols = selector.cols;
7082.
                apiSelector.opts = selector.opts;
7083.
                return api;
7084.
            }
7085.
            return this;
7086.
        },
7087.
    
7088.
    
7089.
        lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
7090.
        {
7091.
            // Bit cheeky...
7092.
            return this.indexOf.apply( this.toArray.reverse(), arguments );
7093.
        },
7094.
    
7095.
    
7096.
        length:  0,
7097.
    
7098.
    
7099.
        map: function ( fn )
7100.
        {
7101.
            var a = [];
7102.
    
7103.
            if ( __arrayProto.map ) {
7104.
                a = __arrayProto.map.call( this, fn, this );
7105.
            }
7106.
            else {
7107.
                // Compatibility for browsers without EMCA-252-5 (JS 1.6)
7108.
                for ( var i=0, ien=this.length ; i<ien ; i++ ) {
7109.
                    a.push( fn.call( this, this[i], i ) );
7110.
                }
7111.
            }
7112.
    
7113.
            return new _Api( this.context, a );
7114.
        },
7115.
    
7116.
    
7117.
        pluck: function ( prop )
7118.
        {
7119.
            return this.map( function ( el ) {
7120.
                return el[ prop ];
7121.
            } );
7122.
        },
7123.
    
7124.
        pop:     __arrayProto.pop,
7125.
    
7126.
    
7127.
        push:    __arrayProto.push,
7128.
    
7129.
    
7130.
        // Does not return an API instance
7131.
        reduce: __arrayProto.reduce || function ( fn, init )
7132.
        {
7133.
            return _fnReduce( this, fn, init, 0, this.length, 1 );
7134.
        },
7135.
    
7136.
    
7137.
        reduceRight: __arrayProto.reduceRight || function ( fn, init )
7138.
        {
7139.
            return _fnReduce( this, fn, init, this.length-1, -1, -1 );
7140.
        },
7141.
    
7142.
    
7143.
        reverse: __arrayProto.reverse,
7144.
    
7145.
    
7146.
        // Object with rows, columns and opts
7147.
        selector: null,
7148.
    
7149.
    
7150.
        shift:   __arrayProto.shift,
7151.
    
7152.
    
7153.
        slice: function () {
7154.
            return new _Api( this.context, this );
7155.
        },
7156.
    
7157.
    
7158.
        sort:    __arrayProto.sort, // ? name - order?
7159.
    
7160.
    
7161.
        splice:  __arrayProto.splice,
7162.
    
7163.
    
7164.
        toArray: function ()
7165.
        {
7166.
            return __arrayProto.slice.call( this );
7167.
        },
7168.
    
7169.
    
7170.
        to$: function ()
7171.
        {
7172.
            return $( this );
7173.
        },
7174.
    
7175.
    
7176.
        toJQuery: function ()
7177.
        {
7178.
            return $( this );
7179.
        },
7180.
    
7181.
    
7182.
        unique: function ()
7183.
        {
7184.
            return new _Api( this.context, _unique(this) );
7185.
        },
7186.
    
7187.
    
7188.
        unshift: __arrayProto.unshift
7189.
    } );
7190.
    
7191.
    
7192.
    _Api.extend = function ( scope, obj, ext )
7193.
    {
7194.
        // Only extend API instances and static properties of the API
7195.
        if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7196.
            return;
7197.
        }
7198.
    
7199.
        var
7200.
            i, ien,
7201.
            struct,
7202.
            methodScoping = function ( scope, fn, struc ) {
7203.
                return function () {
7204.
                    var ret = fn.apply( scope, arguments );
7205.
    
7206.
                    // Method extension
7207.
                    _Api.extend( ret, ret, struc.methodExt );
7208.
                    return ret;
7209.
                };
7210.
            };
7211.
    
7212.
        for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7213.
            struct = ext[i];
7214.
    
7215.
            // Value
7216.
            obj[ struct.name ] = struct.type === 'function' ?
7217.
                methodScoping( scope, struct.val, struct ) :
7218.
                struct.type === 'object' ?
7219.
                    {} :
7220.
                    struct.val;
7221.
    
7222.
            obj[ struct.name ].__dt_wrapper = true;
7223.
    
7224.
            // Property extension
7225.
            _Api.extend( scope, obj[ struct.name ], struct.propExt );
7226.
        }
7227.
    };
7228.
    
7229.
    
7230.
    // @todo - Is there need for an augment function?
7231.
    // _Api.augment = function ( inst, name )
7232.
    // {
7233.
    //     // Find src object in the structure from the name
7234.
    //     var parts = name.split('.');
7235.
    
7236.
    //     _Api.extend( inst, obj );
7237.
    // };
7238.
    
7239.
    
7240.
    //     [
7241.
    //       {
7242.
    //         name:      'data'                -- string   - Property name
7243.
    //         val:       function () {},       -- function - Api method (or undefined if just an object
7244.
    //         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
7245.
    //         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
7246.
    //       },
7247.
    //       {
7248.
    //         name:     'row'
7249.
    //         val:       {},
7250.
    //         methodExt: [ ... ],
7251.
    //         propExt:   [
7252.
    //           {
7253.
    //             name:      'data'
7254.
    //             val:       function () {},
7255.
    //             methodExt: [ ... ],
7256.
    //             propExt:   [ ... ]
7257.
    //           },
7258.
    //           ...
7259.
    //         ]
7260.
    //       }
7261.
    //     ]
7262.
    
7263.
    _Api.register = _api_register = function ( name, val )
7264.
    {
7265.
        if ( $.isArray( name ) ) {
7266.
            for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7267.
                _Api.register( name[j], val );
7268.
            }
7269.
            return;
7270.
        }
7271.
    
7272.
        var
7273.
            i, ien,
7274.
            heir = name.split('.'),
7275.
            struct = __apiStruct,
7276.
            key, method;
7277.
    
7278.
        var find = function ( src, name ) {
7279.
            for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7280.
                if ( src[i].name === name ) {
7281.
                    return src[i];
7282.
                }
7283.
            }
7284.
            return null;
7285.
        };
7286.
    
7287.
        for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7288.
            method = heir[i].indexOf('()') !== -1;
7289.
            key = method ?
7290.
                heir[i].replace('()', '') :
7291.
                heir[i];
7292.
    
7293.
            var src = find( struct, key );
7294.
            if ( ! src ) {
7295.
                src = {
7296.
                    name:      key,
7297.
                    val:       {},
7298.
                    methodExt: [],
7299.
                    propExt:   [],
7300.
                    type:      'object'
7301.
                };
7302.
                struct.push( src );
7303.
            }
7304.
    
7305.
            if ( i === ien-1 ) {
7306.
                src.val = val;
7307.
                src.type = typeof val === 'function' ?
7308.
                    'function' :
7309.
                    $.isPlainObject( val ) ?
7310.
                        'object' :
7311.
                        'other';
7312.
            }
7313.
            else {
7314.
                struct = method ?
7315.
                    src.methodExt :
7316.
                    src.propExt;
7317.
            }
7318.
        }
7319.
    };
7320.
    
7321.
    _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7322.
        _Api.register( pluralName, val );
7323.
    
7324.
        _Api.register( singularName, function () {
7325.
            var ret = val.apply( this, arguments );
7326.
    
7327.
            if ( ret === this ) {
7328.
                // Returned item is the API instance that was passed in, return it
7329.
                return this;
7330.
            }
7331.
            else if ( ret instanceof _Api ) {
7332.
                // New API instance returned, want the value from the first item
7333.
                // in the returned array for the singular result.
7334.
                return ret.length ?
7335.
                    $.isArray( ret[0] ) ?
7336.
                        new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7337.
                        ret[0] :
7338.
                    undefined;
7339.
            }
7340.
    
7341.
            // Non-API return - just fire it back
7342.
            return ret;
7343.
        } );
7344.
    };
7345.
    
7346.
    
7347.
    /**
7348.
     * Selector for HTML tables. Apply the given selector to the give array of
7349.
     * DataTables settings objects.
7350.
     *
7351.
     * @param {string|integer} [selector] jQuery selector string or integer
7352.
     * @param  {array} Array of DataTables settings objects to be filtered
7353.
     * @return {array}
7354.
     * @ignore
7355.
     */
7356.
    var __table_selector = function ( selector, a )
7357.
    {
7358.
        if ( $.isArray(selector) ) {
7359.
            return $.map( selector, function (item) {
7360.
                return __table_selector(item, a);
7361.
            } );
7362.
        }
7363.
    
7364.
        // Integer is used to pick out a table by index
7365.
        if ( typeof selector === 'number' ) {
7366.
            return [ a[ selector ] ];
7367.
        }
7368.
    
7369.
        // Perform a jQuery selector on the table nodes
7370.
        var nodes = $.map( a, function (el, i) {
7371.
            return el.nTable;
7372.
        } );
7373.
    
7374.
        return $(nodes)
7375.
            .filter( selector )
7376.
            .map( function (i) {
7377.
                // Need to translate back from the table node to the settings
7378.
                var idx = $.inArray( this, nodes );
7379.
                return a[ idx ];
7380.
            } )
7381.
            .toArray();
7382.
    };
7383.
    
7384.
    
7385.
    
7386.
    /**
7387.
     * Context selector for the API's context (i.e. the tables the API instance
7388.
     * refers to.
7389.
     *
7390.
     * @name    DataTable.Api#tables
7391.
     * @param {string|integer} [selector] Selector to pick which tables the iterator
7392.
     *   should operate on. If not given, all tables in the current context are
7393.
     *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7394.
     *   select multiple tables or as an integer to select a single table.
7395.
     * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7396.
     */
7397.
    _api_register( 'tables()', function ( selector ) {
7398.
        // A new instance is created if there was a selector specified
7399.
        return selector !== undefined && selector !== null ?
7400.
            new _Api( __table_selector( selector, this.context ) ) :
7401.
            this;
7402.
    } );
7403.
    
7404.
    
7405.
    _api_register( 'table()', function ( selector ) {
7406.
        var tables = this.tables( selector );
7407.
        var ctx = tables.context;
7408.
    
7409.
        // Truncate to the first matched table
7410.
        return ctx.length ?
7411.
            new _Api( ctx[0] ) :
7412.
            tables;
7413.
    } );
7414.
    
7415.
    
7416.
    _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7417.
        return this.iterator( 'table', function ( ctx ) {
7418.
            return ctx.nTable;
7419.
        }, 1 );
7420.
    } );
7421.
    
7422.
    
7423.
    _api_registerPlural( 'tables().body()', 'table().body()' , function () {
7424.
        return this.iterator( 'table', function ( ctx ) {
7425.
            return ctx.nTBody;
7426.
        }, 1 );
7427.
    } );
7428.
    
7429.
    
7430.
    _api_registerPlural( 'tables().header()', 'table().header()' , function () {
7431.
        return this.iterator( 'table', function ( ctx ) {
7432.
            return ctx.nTHead;
7433.
        }, 1 );
7434.
    } );
7435.
    
7436.
    
7437.
    _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7438.
        return this.iterator( 'table', function ( ctx ) {
7439.
            return ctx.nTFoot;
7440.
        }, 1 );
7441.
    } );
7442.
    
7443.
    
7444.
    _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7445.
        return this.iterator( 'table', function ( ctx ) {
7446.
            return ctx.nTableWrapper;
7447.
        }, 1 );
7448.
    } );
7449.
    
7450.
    
7451.
    
7452.
    /**
7453.
     * Redraw the tables in the current context.
7454.
     */
7455.
    _api_register( 'draw()', function ( paging ) {
7456.
        return this.iterator( 'table', function ( settings ) {
7457.
            if ( paging === 'page' ) {
7458.
                _fnDraw( settings );
7459.
            }
7460.
            else {
7461.
                if ( typeof paging === 'string' ) {
7462.
                    paging = paging === 'full-hold' ?
7463.
                        false :
7464.
                        true;
7465.
                }
7466.
    
7467.
                _fnReDraw( settings, paging===false );
7468.
            }
7469.
        } );
7470.
    } );
7471.
    
7472.
    
7473.
    
7474.
    /**
7475.
     * Get the current page index.
7476.
     *
7477.
     * @return {integer} Current page index (zero based)
7478.
     *//**
7479.
     * Set the current page.
7480.
     *
7481.
     * Note that if you attempt to show a page which does not exist, DataTables will
7482.
     * not throw an error, but rather reset the paging.
7483.
     *
7484.
     * @param {integer|string} action The paging action to take. This can be one of:
7485.
     *  * `integer` - The page index to jump to
7486.
     *  * `string` - An action to take:
7487.
     *    * `first` - Jump to first page.
7488.
     *    * `next` - Jump to the next page
7489.
     *    * `previous` - Jump to previous page
7490.
     *    * `last` - Jump to the last page.
7491.
     * @returns {DataTables.Api} this
7492.
     */
7493.
    _api_register( 'page()', function ( action ) {
7494.
        if ( action === undefined ) {
7495.
            return this.page.info().page; // not an expensive call
7496.
        }
7497.
    
7498.
        // else, have an action to take on all tables
7499.
        return this.iterator( 'table', function ( settings ) {
7500.
            _fnPageChange( settings, action );
7501.
        } );
7502.
    } );
7503.
    
7504.
    
7505.
    /**
7506.
     * Paging information for the first table in the current context.
7507.
     *
7508.
     * If you require paging information for another table, use the `table()` method
7509.
     * with a suitable selector.
7510.
     *
7511.
     * @return {object} Object with the following properties set:
7512.
     *  * `page` - Current page index (zero based - i.e. the first page is `0`)
7513.
     *  * `pages` - Total number of pages
7514.
     *  * `start` - Display index for the first record shown on the current page
7515.
     *  * `end` - Display index for the last record shown on the current page
7516.
     *  * `length` - Display length (number of records). Note that generally `start
7517.
     *    + length = end`, but this is not always true, for example if there are
7518.
     *    only 2 records to show on the final page, with a length of 10.
7519.
     *  * `recordsTotal` - Full data set length
7520.
     *  * `recordsDisplay` - Data set length once the current filtering criterion
7521.
     *    are applied.
7522.
     */
7523.
    _api_register( 'page.info()', function ( action ) {
7524.
        if ( this.context.length === 0 ) {
7525.
            return undefined;
7526.
        }
7527.
    
7528.
        var
7529.
            settings   = this.context[0],
7530.
            start      = settings._iDisplayStart,
7531.
            len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
7532.
            visRecords = settings.fnRecordsDisplay(),
7533.
            all        = len === -1;
7534.
    
7535.
        return {
7536.
            "page":           all ? 0 : Math.floor( start / len ),
7537.
            "pages":          all ? 1 : Math.ceil( visRecords / len ),
7538.
            "start":          start,
7539.
            "end":            settings.fnDisplayEnd(),
7540.
            "length":         len,
7541.
            "recordsTotal":   settings.fnRecordsTotal(),
7542.
            "recordsDisplay": visRecords,
7543.
            "serverSide":     _fnDataSource( settings ) === 'ssp'
7544.
        };
7545.
    } );
7546.
    
7547.
    
7548.
    /**
7549.
     * Get the current page length.
7550.
     *
7551.
     * @return {integer} Current page length. Note `-1` indicates that all records
7552.
     *   are to be shown.
7553.
     *//**
7554.
     * Set the current page length.
7555.
     *
7556.
     * @param {integer} Page length to set. Use `-1` to show all records.
7557.
     * @returns {DataTables.Api} this
7558.
     */
7559.
    _api_register( 'page.len()', function ( len ) {
7560.
        // Note that we can't call this function 'length()' because `length`
7561.
        // is a Javascript property of functions which defines how many arguments
7562.
        // the function expects.
7563.
        if ( len === undefined ) {
7564.
            return this.context.length !== 0 ?
7565.
                this.context[0]._iDisplayLength :
7566.
                undefined;
7567.
        }
7568.
    
7569.
        // else, set the page length
7570.
        return this.iterator( 'table', function ( settings ) {
7571.
            _fnLengthChange( settings, len );
7572.
        } );
7573.
    } );
7574.
    
7575.
    
7576.
    
7577.
    var __reload = function ( settings, holdPosition, callback ) {
7578.
        // Use the draw event to trigger a callback
7579.
        if ( callback ) {
7580.
            var api = new _Api( settings );
7581.
    
7582.
            api.one( 'draw', function () {
7583.
                callback( api.ajax.json() );
7584.
            } );
7585.
        }
7586.
    
7587.
        if ( _fnDataSource( settings ) == 'ssp' ) {
7588.
            _fnReDraw( settings, holdPosition );
7589.
        }
7590.
        else {
7591.
            _fnProcessingDisplay( settings, true );
7592.
    
7593.
            // Cancel an existing request
7594.
            var xhr = settings.jqXHR;
7595.
            if ( xhr && xhr.readyState !== 4 ) {
7596.
                xhr.abort();
7597.
            }
7598.
    
7599.
            // Trigger xhr
7600.
            _fnBuildAjax( settings, [], function( json ) {
7601.
                _fnClearTable( settings );
7602.
    
7603.
                var data = _fnAjaxDataSrc( settings, json );
7604.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7605.
                    _fnAddData( settings, data[i] );
7606.
                }
7607.
    
7608.
                _fnReDraw( settings, holdPosition );
7609.
                _fnProcessingDisplay( settings, false );
7610.
            } );
7611.
        }
7612.
    };
7613.
    
7614.
    
7615.
    /**
7616.
     * Get the JSON response from the last Ajax request that DataTables made to the
7617.
     * server. Note that this returns the JSON from the first table in the current
7618.
     * context.
7619.
     *
7620.
     * @return {object} JSON received from the server.
7621.
     */
7622.
    _api_register( 'ajax.json()', function () {
7623.
        var ctx = this.context;
7624.
    
7625.
        if ( ctx.length > 0 ) {
7626.
            return ctx[0].json;
7627.
        }
7628.
    
7629.
        // else return undefined;
7630.
    } );
7631.
    
7632.
    
7633.
    /**
7634.
     * Get the data submitted in the last Ajax request
7635.
     */
7636.
    _api_register( 'ajax.params()', function () {
7637.
        var ctx = this.context;
7638.
    
7639.
        if ( ctx.length > 0 ) {
7640.
            return ctx[0].oAjaxData;
7641.
        }
7642.
    
7643.
        // else return undefined;
7644.
    } );
7645.
    
7646.
    
7647.
    /**
7648.
     * Reload tables from the Ajax data source. Note that this function will
7649.
     * automatically re-draw the table when the remote data has been loaded.
7650.
     *
7651.
     * @param {boolean} [reset=true] Reset (default) or hold the current paging
7652.
     *   position. A full re-sort and re-filter is performed when this method is
7653.
     *   called, which is why the pagination reset is the default action.
7654.
     * @returns {DataTables.Api} this
7655.
     */
7656.
    _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7657.
        return this.iterator( 'table', function (settings) {
7658.
            __reload( settings, resetPaging===false, callback );
7659.
        } );
7660.
    } );
7661.
    
7662.
    
7663.
    /**
7664.
     * Get the current Ajax URL. Note that this returns the URL from the first
7665.
     * table in the current context.
7666.
     *
7667.
     * @return {string} Current Ajax source URL
7668.
     *//**
7669.
     * Set the Ajax URL. Note that this will set the URL for all tables in the
7670.
     * current context.
7671.
     *
7672.
     * @param {string} url URL to set.
7673.
     * @returns {DataTables.Api} this
7674.
     */
7675.
    _api_register( 'ajax.url()', function ( url ) {
7676.
        var ctx = this.context;
7677.
    
7678.
        if ( url === undefined ) {
7679.
            // get
7680.
            if ( ctx.length === 0 ) {
7681.
                return undefined;
7682.
            }
7683.
            ctx = ctx[0];
7684.
    
7685.
            return ctx.ajax ?
7686.
                $.isPlainObject( ctx.ajax ) ?
7687.
                    ctx.ajax.url :
7688.
                    ctx.ajax :
7689.
                ctx.sAjaxSource;
7690.
        }
7691.
    
7692.
        // set
7693.
        return this.iterator( 'table', function ( settings ) {
7694.
            if ( $.isPlainObject( settings.ajax ) ) {
7695.
                settings.ajax.url = url;
7696.
            }
7697.
            else {
7698.
                settings.ajax = url;
7699.
            }
7700.
            // No need to consider sAjaxSource here since DataTables gives priority
7701.
            // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7702.
            // value of `sAjaxSource` redundant.
7703.
        } );
7704.
    } );
7705.
    
7706.
    
7707.
    /**
7708.
     * Load data from the newly set Ajax URL. Note that this method is only
7709.
     * available when `ajax.url()` is used to set a URL. Additionally, this method
7710.
     * has the same effect as calling `ajax.reload()` but is provided for
7711.
     * convenience when setting a new URL. Like `ajax.reload()` it will
7712.
     * automatically redraw the table once the remote data has been loaded.
7713.
     *
7714.
     * @returns {DataTables.Api} this
7715.
     */
7716.
    _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7717.
        // Same as a reload, but makes sense to present it for easy access after a
7718.
        // url change
7719.
        return this.iterator( 'table', function ( ctx ) {
7720.
            __reload( ctx, resetPaging===false, callback );
7721.
        } );
7722.
    } );
7723.
    
7724.
    
7725.
    
7726.
    
7727.
    var _selector_run = function ( type, selector, selectFn, settings, opts )
7728.
    {
7729.
        var
7730.
            out = [], res,
7731.
            a, i, ien, j, jen,
7732.
            selectorType = typeof selector;
7733.
    
7734.
        // Can't just check for isArray here, as an API or jQuery instance might be
7735.
        // given with their array like look
7736.
        if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7737.
            selector = [ selector ];
7738.
        }
7739.
    
7740.
        for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7741.
            // Only split on simple strings - complex expressions will be jQuery selectors
7742.
            a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
7743.
                selector[i].split(',') :
7744.
                [ selector[i] ];
7745.
    
7746.
            for ( j=0, jen=a.length ; j<jen ; j++ ) {
7747.
                res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7748.
    
7749.
                if ( res && res.length ) {
7750.
                    out = out.concat( res );
7751.
                }
7752.
            }
7753.
        }
7754.
    
7755.
        // selector extensions
7756.
        var ext = _ext.selector[ type ];
7757.
        if ( ext.length ) {
7758.
            for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7759.
                out = ext[i]( settings, opts, out );
7760.
            }
7761.
        }
7762.
    
7763.
        return _unique( out );
7764.
    };
7765.
    
7766.
    
7767.
    var _selector_opts = function ( opts )
7768.
    {
7769.
        if ( ! opts ) {
7770.
            opts = {};
7771.
        }
7772.
    
7773.
        // Backwards compatibility for 1.9- which used the terminology filter rather
7774.
        // than search
7775.
        if ( opts.filter && opts.search === undefined ) {
7776.
            opts.search = opts.filter;
7777.
        }
7778.
    
7779.
        return $.extend( {
7780.
            search: 'none',
7781.
            order: 'current',
7782.
            page: 'all'
7783.
        }, opts );
7784.
    };
7785.
    
7786.
    
7787.
    var _selector_first = function ( inst )
7788.
    {
7789.
        // Reduce the API instance to the first item found
7790.
        for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7791.
            if ( inst[i].length > 0 ) {
7792.
                // Assign the first element to the first item in the instance
7793.
                // and truncate the instance and context
7794.
                inst[0] = inst[i];
7795.
                inst[0].length = 1;
7796.
                inst.length = 1;
7797.
                inst.context = [ inst.context[i] ];
7798.
    
7799.
                return inst;
7800.
            }
7801.
        }
7802.
    
7803.
        // Not found - return an empty instance
7804.
        inst.length = 0;
7805.
        return inst;
7806.
    };
7807.
    
7808.
    
7809.
    var _selector_row_indexes = function ( settings, opts )
7810.
    {
7811.
        var
7812.
            i, ien, tmp, a=[],
7813.
            displayFiltered = settings.aiDisplay,
7814.
            displayMaster = settings.aiDisplayMaster;
7815.
    
7816.
        var
7817.
            search = opts.search,  // none, applied, removed
7818.
            order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
7819.
            page   = opts.page;    // all, current
7820.
    
7821.
        if ( _fnDataSource( settings ) == 'ssp' ) {
7822.
            // In server-side processing mode, most options are irrelevant since
7823.
            // rows not shown don't exist and the index order is the applied order
7824.
            // Removed is a special case - for consistency just return an empty
7825.
            // array
7826.
            return search === 'removed' ?
7827.
                [] :
7828.
                _range( 0, displayMaster.length );
7829.
        }
7830.
        else if ( page == 'current' ) {
7831.
            // Current page implies that order=current and fitler=applied, since it is
7832.
            // fairly senseless otherwise, regardless of what order and search actually
7833.
            // are
7834.
            for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7835.
                a.push( displayFiltered[i] );
7836.
            }
7837.
        }
7838.
        else if ( order == 'current' || order == 'applied' ) {
7839.
            if ( search == 'none') {
7840.
                a = displayMaster.slice();
7841.
            }
7842.
            else if ( search == 'applied' ) {
7843.
                a = displayFiltered.slice();
7844.
            }
7845.
            else if ( search == 'removed' ) {
7846.
                // O(n+m) solution by creating a hash map
7847.
                var displayFilteredMap = {};
7848.
    
7849.
                for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
7850.
                    displayFilteredMap[displayFiltered[i]] = null;
7851.
                }
7852.
    
7853.
                a = $.map( displayMaster, function (el) {
7854.
                    return ! displayFilteredMap.hasOwnProperty(el) ?
7855.
                        el :
7856.
                        null;
7857.
                } );
7858.
            }
7859.
        }
7860.
        else if ( order == 'index' || order == 'original' ) {
7861.
            for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7862.
                if ( search == 'none' ) {
7863.
                    a.push( i );
7864.
                }
7865.
                else { // applied | removed
7866.
                    tmp = $.inArray( i, displayFiltered );
7867.
    
7868.
                    if ((tmp === -1 && search == 'removed') ||
7869.
                        (tmp >= 0   && search == 'applied') )
7870.
                    {
7871.
                        a.push( i );
7872.
                    }
7873.
                }
7874.
            }
7875.
        }
7876.
    
7877.
        return a;
7878.
    };
7879.
    
7880.
    
7881.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7882.
     * Rows
7883.
     *
7884.
     * {}          - no selector - use all available rows
7885.
     * {integer}   - row aoData index
7886.
     * {node}      - TR node
7887.
     * {string}    - jQuery selector to apply to the TR elements
7888.
     * {array}     - jQuery array of nodes, or simply an array of TR nodes
7889.
     *
7890.
     */
7891.
    var __row_selector = function ( settings, selector, opts )
7892.
    {
7893.
        var rows;
7894.
        var run = function ( sel ) {
7895.
            var selInt = _intVal( sel );
7896.
            var i, ien;
7897.
            var aoData = settings.aoData;
7898.
    
7899.
            // Short cut - selector is a number and no options provided (default is
7900.
            // all records, so no need to check if the index is in there, since it
7901.
            // must be - dev error if the index doesn't exist).
7902.
            if ( selInt !== null && ! opts ) {
7903.
                return [ selInt ];
7904.
            }
7905.
    
7906.
            if ( ! rows ) {
7907.
                rows = _selector_row_indexes( settings, opts );
7908.
            }
7909.
    
7910.
            if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7911.
                // Selector - integer
7912.
                return [ selInt ];
7913.
            }
7914.
            else if ( sel === null || sel === undefined || sel === '' ) {
7915.
                // Selector - none
7916.
                return rows;
7917.
            }
7918.
    
7919.
            // Selector - function
7920.
            if ( typeof sel === 'function' ) {
7921.
                return $.map( rows, function (idx) {
7922.
                    var row = aoData[ idx ];
7923.
                    return sel( idx, row._aData, row.nTr ) ? idx : null;
7924.
                } );
7925.
            }
7926.
    
7927.
            // Selector - node
7928.
            if ( sel.nodeName ) {
7929.
                var rowIdx = sel._DT_RowIndex;  // Property added by DT for fast lookup
7930.
                var cellIdx = sel._DT_CellIndex;
7931.
    
7932.
                if ( rowIdx !== undefined ) {
7933.
                    // Make sure that the row is actually still present in the table
7934.
                    return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
7935.
                        [ rowIdx ] :
7936.
                        [];
7937.
                }
7938.
                else if ( cellIdx ) {
7939.
                    return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?
7940.
                        [ cellIdx.row ] :
7941.
                        [];
7942.
                }
7943.
                else {
7944.
                    var host = $(sel).closest('*[data-dt-row]');
7945.
                    return host.length ?
7946.
                        [ host.data('dt-row') ] :
7947.
                        [];
7948.
                }
7949.
            }
7950.
    
7951.
            // ID selector. Want to always be able to select rows by id, regardless
7952.
            // of if the tr element has been created or not, so can't rely upon
7953.
            // jQuery here - hence a custom implementation. This does not match
7954.
            // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7955.
            // but to select it using a CSS selector engine (like Sizzle or
7956.
            // querySelect) it would need to need to be escaped for some characters.
7957.
            // DataTables simplifies this for row selectors since you can select
7958.
            // only a row. A # indicates an id any anything that follows is the id -
7959.
            // unescaped.
7960.
            if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7961.
                // get row index from id
7962.
                var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7963.
                if ( rowObj !== undefined ) {
7964.
                    return [ rowObj.idx ];
7965.
                }
7966.
    
7967.
                // need to fall through to jQuery in case there is DOM id that
7968.
                // matches
7969.
            }
7970.
            
7971.
            // Get nodes in the order from the `rows` array with null values removed
7972.
            var nodes = _removeEmpty(
7973.
                _pluck_order( settings.aoData, rows, 'nTr' )
7974.
            );
7975.
    
7976.
            // Selector - jQuery selector string, array of nodes or jQuery object/
7977.
            // As jQuery's .filter() allows jQuery objects to be passed in filter,
7978.
            // it also allows arrays, so this will cope with all three options
7979.
            return $(nodes)
7980.
                .filter( sel )
7981.
                .map( function () {
7982.
                    return this._DT_RowIndex;
7983.
                } )
7984.
                .toArray();
7985.
        };
7986.
    
7987.
        return _selector_run( 'row', selector, run, settings, opts );
7988.
    };
7989.
    
7990.
    
7991.
    _api_register( 'rows()', function ( selector, opts ) {
7992.
        // argument shifting
7993.
        if ( selector === undefined ) {
7994.
            selector = '';
7995.
        }
7996.
        else if ( $.isPlainObject( selector ) ) {
7997.
            opts = selector;
7998.
            selector = '';
7999.
        }
8000.
    
8001.
        opts = _selector_opts( opts );
8002.
    
8003.
        var inst = this.iterator( 'table', function ( settings ) {
8004.
            return __row_selector( settings, selector, opts );
8005.
        }, 1 );
8006.
    
8007.
        // Want argument shifting here and in __row_selector?
8008.
        inst.selector.rows = selector;
8009.
        inst.selector.opts = opts;
8010.
    
8011.
        return inst;
8012.
    } );
8013.
    
8014.
    _api_register( 'rows().nodes()', function () {
8015.
        return this.iterator( 'row', function ( settings, row ) {
8016.
            return settings.aoData[ row ].nTr || undefined;
8017.
        }, 1 );
8018.
    } );
8019.
    
8020.
    _api_register( 'rows().data()', function () {
8021.
        return this.iterator( true, 'rows', function ( settings, rows ) {
8022.
            return _pluck_order( settings.aoData, rows, '_aData' );
8023.
        }, 1 );
8024.
    } );
8025.
    
8026.
    _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
8027.
        return this.iterator( 'row', function ( settings, row ) {
8028.
            var r = settings.aoData[ row ];
8029.
            return type === 'search' ? r._aFilterData : r._aSortData;
8030.
        }, 1 );
8031.
    } );
8032.
    
8033.
    _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
8034.
        return this.iterator( 'row', function ( settings, row ) {
8035.
            _fnInvalidate( settings, row, src );
8036.
        } );
8037.
    } );
8038.
    
8039.
    _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
8040.
        return this.iterator( 'row', function ( settings, row ) {
8041.
            return row;
8042.
        }, 1 );
8043.
    } );
8044.
    
8045.
    _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
8046.
        var a = [];
8047.
        var context = this.context;
8048.
    
8049.
        // `iterator` will drop undefined values, but in this case we want them
8050.
        for ( var i=0, ien=context.length ; i<ien ; i++ ) {
8051.
            for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
8052.
                var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
8053.
                a.push( (hash === true ? '#' : '' )+ id );
8054.
            }
8055.
        }
8056.
    
8057.
        return new _Api( context, a );
8058.
    } );
8059.
    
8060.
    _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
8061.
        var that = this;
8062.
    
8063.
        this.iterator( 'row', function ( settings, row, thatIdx ) {
8064.
            var data = settings.aoData;
8065.
            var rowData = data[ row ];
8066.
            var i, ien, j, jen;
8067.
            var loopRow, loopCells;
8068.
    
8069.
            data.splice( row, 1 );
8070.
    
8071.
            // Update the cached indexes
8072.
            for ( i=0, ien=data.length ; i<ien ; i++ ) {
8073.
                loopRow = data[i];
8074.
                loopCells = loopRow.anCells;
8075.
    
8076.
                // Rows
8077.
                if ( loopRow.nTr !== null ) {
8078.
                    loopRow.nTr._DT_RowIndex = i;
8079.
                }
8080.
    
8081.
                // Cells
8082.
                if ( loopCells !== null ) {
8083.
                    for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
8084.
                        loopCells[j]._DT_CellIndex.row = i;
8085.
                    }
8086.
                }
8087.
            }
8088.
    
8089.
            // Delete from the display arrays
8090.
            _fnDeleteIndex( settings.aiDisplayMaster, row );
8091.
            _fnDeleteIndex( settings.aiDisplay, row );
8092.
            _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
8093.
    
8094.
            // For server-side processing tables - subtract the deleted row from the count
8095.
            if ( settings._iRecordsDisplay > 0 ) {
8096.
                settings._iRecordsDisplay--;
8097.
            }
8098.
    
8099.
            // Check for an 'overflow' they case for displaying the table
8100.
            _fnLengthOverflow( settings );
8101.
    
8102.
            // Remove the row's ID reference if there is one
8103.
            var id = settings.rowIdFn( rowData._aData );
8104.
            if ( id !== undefined ) {
8105.
                delete settings.aIds[ id ];
8106.
            }
8107.
        } );
8108.
    
8109.
        this.iterator( 'table', function ( settings ) {
8110.
            for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
8111.
                settings.aoData[i].idx = i;
8112.
            }
8113.
        } );
8114.
    
8115.
        return this;
8116.
    } );
8117.
    
8118.
    
8119.
    _api_register( 'rows.add()', function ( rows ) {
8120.
        var newRows = this.iterator( 'table', function ( settings ) {
8121.
                var row, i, ien;
8122.
                var out = [];
8123.
    
8124.
                for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8125.
                    row = rows[i];
8126.
    
8127.
                    if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8128.
                        out.push( _fnAddTr( settings, row )[0] );
8129.
                    }
8130.
                    else {
8131.
                        out.push( _fnAddData( settings, row ) );
8132.
                    }
8133.
                }
8134.
    
8135.
                return out;
8136.
            }, 1 );
8137.
    
8138.
        // Return an Api.rows() extended instance, so rows().nodes() etc can be used
8139.
        var modRows = this.rows( -1 );
8140.
        modRows.pop();
8141.
        $.merge( modRows, newRows );
8142.
    
8143.
        return modRows;
8144.
    } );
8145.
    
8146.
    
8147.
    
8148.
    
8149.
    
8150.
    /**
8151.
     *
8152.
     */
8153.
    _api_register( 'row()', function ( selector, opts ) {
8154.
        return _selector_first( this.rows( selector, opts ) );
8155.
    } );
8156.
    
8157.
    
8158.
    _api_register( 'row().data()', function ( data ) {
8159.
        var ctx = this.context;
8160.
    
8161.
        if ( data === undefined ) {
8162.
            // Get
8163.
            return ctx.length && this.length ?
8164.
                ctx[0].aoData[ this[0] ]._aData :
8165.
                undefined;
8166.
        }
8167.
    
8168.
        // Set
8169.
        var row = ctx[0].aoData[ this[0] ];
8170.
        row._aData = data;
8171.
    
8172.
        // If the DOM has an id, and the data source is an array
8173.
        if ( $.isArray( data ) && row.nTr && row.nTr.id ) {
8174.
            _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
8175.
        }
8176.
    
8177.
        // Automatically invalidate
8178.
        _fnInvalidate( ctx[0], this[0], 'data' );
8179.
    
8180.
        return this;
8181.
    } );
8182.
    
8183.
    
8184.
    _api_register( 'row().node()', function () {
8185.
        var ctx = this.context;
8186.
    
8187.
        return ctx.length && this.length ?
8188.
            ctx[0].aoData[ this[0] ].nTr || null :
8189.
            null;
8190.
    } );
8191.
    
8192.
    
8193.
    _api_register( 'row.add()', function ( row ) {
8194.
        // Allow a jQuery object to be passed in - only a single row is added from
8195.
        // it though - the first element in the set
8196.
        if ( row instanceof $ && row.length ) {
8197.
            row = row[0];
8198.
        }
8199.
    
8200.
        var rows = this.iterator( 'table', function ( settings ) {
8201.
            if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8202.
                return _fnAddTr( settings, row )[0];
8203.
            }
8204.
            return _fnAddData( settings, row );
8205.
        } );
8206.
    
8207.
        // Return an Api.rows() extended instance, with the newly added row selected
8208.
        return this.row( rows[0] );
8209.
    } );
8210.
    
8211.
    
8212.
    
8213.
    var __details_add = function ( ctx, row, data, klass )
8214.
    {
8215.
        // Convert to array of TR elements
8216.
        var rows = [];
8217.
        var addRow = function ( r, k ) {
8218.
            // Recursion to allow for arrays of jQuery objects
8219.
            if ( $.isArray( r ) || r instanceof $ ) {
8220.
                for ( var i=0, ien=r.length ; i<ien ; i++ ) {
8221.
                    addRow( r[i], k );
8222.
                }
8223.
                return;
8224.
            }
8225.
    
8226.
            // If we get a TR element, then just add it directly - up to the dev
8227.
            // to add the correct number of columns etc
8228.
            if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
8229.
                rows.push( r );
8230.
            }
8231.
            else {
8232.
                // Otherwise create a row with a wrapper
8233.
                var created = $('<tr><td/></tr>').addClass( k );
8234.
                $('td', created)
8235.
                    .addClass( k )
8236.
                    .html( r )
8237.
                    [0].colSpan = _fnVisbleColumns( ctx );
8238.
    
8239.
                rows.push( created[0] );
8240.
            }
8241.
        };
8242.
    
8243.
        addRow( data, klass );
8244.
    
8245.
        if ( row._details ) {
8246.
            row._details.detach();
8247.
        }
8248.
    
8249.
        row._details = $(rows);
8250.
    
8251.
        // If the children were already shown, that state should be retained
8252.
        if ( row._detailsShow ) {
8253.
            row._details.insertAfter( row.nTr );
8254.
        }
8255.
    };
8256.
    
8257.
    
8258.
    var __details_remove = function ( api, idx )
8259.
    {
8260.
        var ctx = api.context;
8261.
    
8262.
        if ( ctx.length ) {
8263.
            var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8264.
    
8265.
            if ( row && row._details ) {
8266.
                row._details.remove();
8267.
    
8268.
                row._detailsShow = undefined;
8269.
                row._details = undefined;
8270.
            }
8271.
        }
8272.
    };
8273.
    
8274.
    
8275.
    var __details_display = function ( api, show ) {
8276.
        var ctx = api.context;
8277.
    
8278.
        if ( ctx.length && api.length ) {
8279.
            var row = ctx[0].aoData[ api[0] ];
8280.
    
8281.
            if ( row._details ) {
8282.
                row._detailsShow = show;
8283.
    
8284.
                if ( show ) {
8285.
                    row._details.insertAfter( row.nTr );
8286.
                }
8287.
                else {
8288.
                    row._details.detach();
8289.
                }
8290.
    
8291.
                __details_events( ctx[0] );
8292.
            }
8293.
        }
8294.
    };
8295.
    
8296.
    
8297.
    var __details_events = function ( settings )
8298.
    {
8299.
        var api = new _Api( settings );
8300.
        var namespace = '.dt.DT_details';
8301.
        var drawEvent = 'draw'+namespace;
8302.
        var colvisEvent = 'column-visibility'+namespace;
8303.
        var destroyEvent = 'destroy'+namespace;
8304.
        var data = settings.aoData;
8305.
    
8306.
        api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8307.
    
8308.
        if ( _pluck( data, '_details' ).length > 0 ) {
8309.
            // On each draw, insert the required elements into the document
8310.
            api.on( drawEvent, function ( e, ctx ) {
8311.
                if ( settings !== ctx ) {
8312.
                    return;
8313.
                }
8314.
    
8315.
                api.rows( {page:'current'} ).eq(0).each( function (idx) {
8316.
                    // Internal data grab
8317.
                    var row = data[ idx ];
8318.
    
8319.
                    if ( row._detailsShow ) {
8320.
                        row._details.insertAfter( row.nTr );
8321.
                    }
8322.
                } );
8323.
            } );
8324.
    
8325.
            // Column visibility change - update the colspan
8326.
            api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8327.
                if ( settings !== ctx ) {
8328.
                    return;
8329.
                }
8330.
    
8331.
                // Update the colspan for the details rows (note, only if it already has
8332.
                // a colspan)
8333.
                var row, visible = _fnVisbleColumns( ctx );
8334.
    
8335.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8336.
                    row = data[i];
8337.
    
8338.
                    if ( row._details ) {
8339.
                        row._details.children('td[colspan]').attr('colspan', visible );
8340.
                    }
8341.
                }
8342.
            } );
8343.
    
8344.
            // Table destroyed - nuke any child rows
8345.
            api.on( destroyEvent, function ( e, ctx ) {
8346.
                if ( settings !== ctx ) {
8347.
                    return;
8348.
                }
8349.
    
8350.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8351.
                    if ( data[i]._details ) {
8352.
                        __details_remove( api, i );
8353.
                    }
8354.
                }
8355.
            } );
8356.
        }
8357.
    };
8358.
    
8359.
    // Strings for the method names to help minification
8360.
    var _emp = '';
8361.
    var _child_obj = _emp+'row().child';
8362.
    var _child_mth = _child_obj+'()';
8363.
    
8364.
    // data can be:
8365.
    //  tr
8366.
    //  string
8367.
    //  jQuery or array of any of the above
8368.
    _api_register( _child_mth, function ( data, klass ) {
8369.
        var ctx = this.context;
8370.
    
8371.
        if ( data === undefined ) {
8372.
            // get
8373.
            return ctx.length && this.length ?
8374.
                ctx[0].aoData[ this[0] ]._details :
8375.
                undefined;
8376.
        }
8377.
        else if ( data === true ) {
8378.
            // show
8379.
            this.child.show();
8380.
        }
8381.
        else if ( data === false ) {
8382.
            // remove
8383.
            __details_remove( this );
8384.
        }
8385.
        else if ( ctx.length && this.length ) {
8386.
            // set
8387.
            __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8388.
        }
8389.
    
8390.
        return this;
8391.
    } );
8392.
    
8393.
    
8394.
    _api_register( [
8395.
        _child_obj+'.show()',
8396.
        _child_mth+'.show()' // only when `child()` was called with parameters (without
8397.
    ], function ( show ) {   // it returns an object and this method is not executed)
8398.
        __details_display( this, true );
8399.
        return this;
8400.
    } );
8401.
    
8402.
    
8403.
    _api_register( [
8404.
        _child_obj+'.hide()',
8405.
        _child_mth+'.hide()' // only when `child()` was called with parameters (without
8406.
    ], function () {         // it returns an object and this method is not executed)
8407.
        __details_display( this, false );
8408.
        return this;
8409.
    } );
8410.
    
8411.
    
8412.
    _api_register( [
8413.
        _child_obj+'.remove()',
8414.
        _child_mth+'.remove()' // only when `child()` was called with parameters (without
8415.
    ], function () {           // it returns an object and this method is not executed)
8416.
        __details_remove( this );
8417.
        return this;
8418.
    } );
8419.
    
8420.
    
8421.
    _api_register( _child_obj+'.isShown()', function () {
8422.
        var ctx = this.context;
8423.
    
8424.
        if ( ctx.length && this.length ) {
8425.
            // _detailsShown as false or undefined will fall through to return false
8426.
            return ctx[0].aoData[ this[0] ]._detailsShow || false;
8427.
        }
8428.
        return false;
8429.
    } );
8430.
    
8431.
    
8432.
    
8433.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8434.
     * Columns
8435.
     *
8436.
     * {integer}           - column index (>=0 count from left, <0 count from right)
8437.
     * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
8438.
     * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
8439.
     * "{string}:name"     - column name
8440.
     * "{string}"          - jQuery selector on column header nodes
8441.
     *
8442.
     */
8443.
    
8444.
    // can be an array of these items, comma separated list, or an array of comma
8445.
    // separated lists
8446.
    
8447.
    var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8448.
    
8449.
    
8450.
    // r1 and r2 are redundant - but it means that the parameters match for the
8451.
    // iterator callback in columns().data()
8452.
    var __columnData = function ( settings, column, r1, r2, rows ) {
8453.
        var a = [];
8454.
        for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8455.
            a.push( _fnGetCellData( settings, rows[row], column ) );
8456.
        }
8457.
        return a;
8458.
    };
8459.
    
8460.
    
8461.
    var __column_selector = function ( settings, selector, opts )
8462.
    {
8463.
        var
8464.
            columns = settings.aoColumns,
8465.
            names = _pluck( columns, 'sName' ),
8466.
            nodes = _pluck( columns, 'nTh' );
8467.
    
8468.
        var run = function ( s ) {
8469.
            var selInt = _intVal( s );
8470.
    
8471.
            // Selector - all
8472.
            if ( s === '' ) {
8473.
                return _range( columns.length );
8474.
            }
8475.
    
8476.
            // Selector - index
8477.
            if ( selInt !== null ) {
8478.
                return [ selInt >= 0 ?
8479.
                    selInt : // Count from left
8480.
                    columns.length + selInt // Count from right (+ because its a negative value)
8481.
                ];
8482.
            }
8483.
    
8484.
            // Selector = function
8485.
            if ( typeof s === 'function' ) {
8486.
                var rows = _selector_row_indexes( settings, opts );
8487.
    
8488.
                return $.map( columns, function (col, idx) {
8489.
                    return s(
8490.
                            idx,
8491.
                            __columnData( settings, idx, 0, 0, rows ),
8492.
                            nodes[ idx ]
8493.
                        ) ? idx : null;
8494.
                } );
8495.
            }
8496.
    
8497.
            // jQuery or string selector
8498.
            var match = typeof s === 'string' ?
8499.
                s.match( __re_column_selector ) :
8500.
                '';
8501.
    
8502.
            if ( match ) {
8503.
                switch( match[2] ) {
8504.
                    case 'visIdx':
8505.
                    case 'visible':
8506.
                        var idx = parseInt( match[1], 10 );
8507.
                        // Visible index given, convert to column index
8508.
                        if ( idx < 0 ) {
8509.
                            // Counting from the right
8510.
                            var visColumns = $.map( columns, function (col,i) {
8511.
                                return col.bVisible ? i : null;
8512.
                            } );
8513.
                            return [ visColumns[ visColumns.length + idx ] ];
8514.
                        }
8515.
                        // Counting from the left
8516.
                        return [ _fnVisibleToColumnIndex( settings, idx ) ];
8517.
    
8518.
                    case 'name':
8519.
                        // match by name. `names` is column index complete and in order
8520.
                        return $.map( names, function (name, i) {
8521.
                            return name === match[1] ? i : null;
8522.
                        } );
8523.
    
8524.
                    default:
8525.
                        return [];
8526.
                }
8527.
            }
8528.
    
8529.
            // Cell in the table body
8530.
            if ( s.nodeName && s._DT_CellIndex ) {
8531.
                return [ s._DT_CellIndex.column ];
8532.
            }
8533.
    
8534.
            // jQuery selector on the TH elements for the columns
8535.
            var jqResult = $( nodes )
8536.
                .filter( s )
8537.
                .map( function () {
8538.
                    return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8539.
                } )
8540.
                .toArray();
8541.
    
8542.
            if ( jqResult.length || ! s.nodeName ) {
8543.
                return jqResult;
8544.
            }
8545.
    
8546.
            // Otherwise a node which might have a `dt-column` data attribute, or be
8547.
            // a child or such an element
8548.
            var host = $(s).closest('*[data-dt-column]');
8549.
            return host.length ?
8550.
                [ host.data('dt-column') ] :
8551.
                [];
8552.
        };
8553.
    
8554.
        return _selector_run( 'column', selector, run, settings, opts );
8555.
    };
8556.
    
8557.
    
8558.
    var __setColumnVis = function ( settings, column, vis ) {
8559.
        var
8560.
            cols = settings.aoColumns,
8561.
            col  = cols[ column ],
8562.
            data = settings.aoData,
8563.
            row, cells, i, ien, tr;
8564.
    
8565.
        // Get
8566.
        if ( vis === undefined ) {
8567.
            return col.bVisible;
8568.
        }
8569.
    
8570.
        // Set
8571.
        // No change
8572.
        if ( col.bVisible === vis ) {
8573.
            return;
8574.
        }
8575.
    
8576.
        if ( vis ) {
8577.
            // Insert column
8578.
            // Need to decide if we should use appendChild or insertBefore
8579.
            var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8580.
    
8581.
            for ( i=0, ien=data.length ; i<ien ; i++ ) {
8582.
                tr = data[i].nTr;
8583.
                cells = data[i].anCells;
8584.
    
8585.
                if ( tr ) {
8586.
                    // insertBefore can act like appendChild if 2nd arg is null
8587.
                    tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8588.
                }
8589.
            }
8590.
        }
8591.
        else {
8592.
            // Remove column
8593.
            $( _pluck( settings.aoData, 'anCells', column ) ).detach();
8594.
        }
8595.
    
8596.
        // Common actions
8597.
        col.bVisible = vis;
8598.
    };
8599.
    
8600.
    
8601.
    _api_register( 'columns()', function ( selector, opts ) {
8602.
        // argument shifting
8603.
        if ( selector === undefined ) {
8604.
            selector = '';
8605.
        }
8606.
        else if ( $.isPlainObject( selector ) ) {
8607.
            opts = selector;
8608.
            selector = '';
8609.
        }
8610.
    
8611.
        opts = _selector_opts( opts );
8612.
    
8613.
        var inst = this.iterator( 'table', function ( settings ) {
8614.
            return __column_selector( settings, selector, opts );
8615.
        }, 1 );
8616.
    
8617.
        // Want argument shifting here and in _row_selector?
8618.
        inst.selector.cols = selector;
8619.
        inst.selector.opts = opts;
8620.
    
8621.
        return inst;
8622.
    } );
8623.
    
8624.
    _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8625.
        return this.iterator( 'column', function ( settings, column ) {
8626.
            return settings.aoColumns[column].nTh;
8627.
        }, 1 );
8628.
    } );
8629.
    
8630.
    _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8631.
        return this.iterator( 'column', function ( settings, column ) {
8632.
            return settings.aoColumns[column].nTf;
8633.
        }, 1 );
8634.
    } );
8635.
    
8636.
    _api_registerPlural( 'columns().data()', 'column().data()', function () {
8637.
        return this.iterator( 'column-rows', __columnData, 1 );
8638.
    } );
8639.
    
8640.
    _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8641.
        return this.iterator( 'column', function ( settings, column ) {
8642.
            return settings.aoColumns[column].mData;
8643.
        }, 1 );
8644.
    } );
8645.
    
8646.
    _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8647.
        return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8648.
            return _pluck_order( settings.aoData, rows,
8649.
                type === 'search' ? '_aFilterData' : '_aSortData', column
8650.
            );
8651.
        }, 1 );
8652.
    } );
8653.
    
8654.
    _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8655.
        return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8656.
            return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8657.
        }, 1 );
8658.
    } );
8659.
    
8660.
    _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8661.
        var that = this;
8662.
        var ret = this.iterator( 'column', function ( settings, column ) {
8663.
            if ( vis === undefined ) {
8664.
                return settings.aoColumns[ column ].bVisible;
8665.
            } // else
8666.
            __setColumnVis( settings, column, vis );
8667.
        } );
8668.
    
8669.
        // Group the column visibility changes
8670.
        if ( vis !== undefined ) {
8671.
            this.iterator( 'table', function ( settings ) {
8672.
                // Redraw the header after changes
8673.
                _fnDrawHead( settings, settings.aoHeader );
8674.
                _fnDrawHead( settings, settings.aoFooter );
8675.
        
8676.
                // Update colspan for no records display. Child rows and extensions will use their own
8677.
                // listeners to do this - only need to update the empty table item here
8678.
                if ( ! settings.aiDisplay.length ) {
8679.
                    $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
8680.
                }
8681.
        
8682.
                _fnSaveState( settings );
8683.
    
8684.
                // Second loop once the first is done for events
8685.
                that.iterator( 'column', function ( settings, column ) {
8686.
                    _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
8687.
                } );
8688.
    
8689.
                if ( calc === undefined || calc ) {
8690.
                    that.columns.adjust();
8691.
                }
8692.
            });
8693.
        }
8694.
    
8695.
        return ret;
8696.
    } );
8697.
    
8698.
    _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8699.
        return this.iterator( 'column', function ( settings, column ) {
8700.
            return type === 'visible' ?
8701.
                _fnColumnIndexToVisible( settings, column ) :
8702.
                column;
8703.
        }, 1 );
8704.
    } );
8705.
    
8706.
    _api_register( 'columns.adjust()', function () {
8707.
        return this.iterator( 'table', function ( settings ) {
8708.
            _fnAdjustColumnSizing( settings );
8709.
        }, 1 );
8710.
    } );
8711.
    
8712.
    _api_register( 'column.index()', function ( type, idx ) {
8713.
        if ( this.context.length !== 0 ) {
8714.
            var ctx = this.context[0];
8715.
    
8716.
            if ( type === 'fromVisible' || type === 'toData' ) {
8717.
                return _fnVisibleToColumnIndex( ctx, idx );
8718.
            }
8719.
            else if ( type === 'fromData' || type === 'toVisible' ) {
8720.
                return _fnColumnIndexToVisible( ctx, idx );
8721.
            }
8722.
        }
8723.
    } );
8724.
    
8725.
    _api_register( 'column()', function ( selector, opts ) {
8726.
        return _selector_first( this.columns( selector, opts ) );
8727.
    } );
8728.
    
8729.
    
8730.
    
8731.
    var __cell_selector = function ( settings, selector, opts )
8732.
    {
8733.
        var data = settings.aoData;
8734.
        var rows = _selector_row_indexes( settings, opts );
8735.
        var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8736.
        var allCells = $( [].concat.apply([], cells) );
8737.
        var row;
8738.
        var columns = settings.aoColumns.length;
8739.
        var a, i, ien, j, o, host;
8740.
    
8741.
        var run = function ( s ) {
8742.
            var fnSelector = typeof s === 'function';
8743.
    
8744.
            if ( s === null || s === undefined || fnSelector ) {
8745.
                // All cells and function selectors
8746.
                a = [];
8747.
    
8748.
                for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8749.
                    row = rows[i];
8750.
    
8751.
                    for ( j=0 ; j<columns ; j++ ) {
8752.
                        o = {
8753.
                            row: row,
8754.
                            column: j
8755.
                        };
8756.
    
8757.
                        if ( fnSelector ) {
8758.
                            // Selector - function
8759.
                            host = data[ row ];
8760.
    
8761.
                            if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8762.
                                a.push( o );
8763.
                            }
8764.
                        }
8765.
                        else {
8766.
                            // Selector - all
8767.
                            a.push( o );
8768.
                        }
8769.
                    }
8770.
                }
8771.
    
8772.
                return a;
8773.
            }
8774.
            
8775.
            // Selector - index
8776.
            if ( $.isPlainObject( s ) ) {
8777.
                // Valid cell index and its in the array of selectable rows
8778.
                return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
8779.
                    [s] :
8780.
                    [];
8781.
            }
8782.
    
8783.
            // Selector - jQuery filtered cells
8784.
            var jqResult = allCells
8785.
                .filter( s )
8786.
                .map( function (i, el) {
8787.
                    return { // use a new object, in case someone changes the values
8788.
                        row:    el._DT_CellIndex.row,
8789.
                        column: el._DT_CellIndex.column
8790.
                     };
8791.
                } )
8792.
                .toArray();
8793.
    
8794.
            if ( jqResult.length || ! s.nodeName ) {
8795.
                return jqResult;
8796.
            }
8797.
    
8798.
            // Otherwise the selector is a node, and there is one last option - the
8799.
            // element might be a child of an element which has dt-row and dt-column
8800.
            // data attributes
8801.
            host = $(s).closest('*[data-dt-row]');
8802.
            return host.length ?
8803.
                [ {
8804.
                    row: host.data('dt-row'),
8805.
                    column: host.data('dt-column')
8806.
                } ] :
8807.
                [];
8808.
        };
8809.
    
8810.
        return _selector_run( 'cell', selector, run, settings, opts );
8811.
    };
8812.
    
8813.
    
8814.
    
8815.
    
8816.
    _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8817.
        // Argument shifting
8818.
        if ( $.isPlainObject( rowSelector ) ) {
8819.
            // Indexes
8820.
            if ( rowSelector.row === undefined ) {
8821.
                // Selector options in first parameter
8822.
                opts = rowSelector;
8823.
                rowSelector = null;
8824.
            }
8825.
            else {
8826.
                // Cell index objects in first parameter
8827.
                opts = columnSelector;
8828.
                columnSelector = null;
8829.
            }
8830.
        }
8831.
        if ( $.isPlainObject( columnSelector ) ) {
8832.
            opts = columnSelector;
8833.
            columnSelector = null;
8834.
        }
8835.
    
8836.
        // Cell selector
8837.
        if ( columnSelector === null || columnSelector === undefined ) {
8838.
            return this.iterator( 'table', function ( settings ) {
8839.
                return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8840.
            } );
8841.
        }
8842.
    
8843.
        // The default built in options need to apply to row and columns
8844.
        var internalOpts = opts ? {
8845.
            page: opts.page,
8846.
            order: opts.order,
8847.
            search: opts.search
8848.
        } : {};
8849.
    
8850.
        // Row + column selector
8851.
        var columns = this.columns( columnSelector, internalOpts );
8852.
        var rows = this.rows( rowSelector, internalOpts );
8853.
        var i, ien, j, jen;
8854.
    
8855.
        var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
8856.
            var a = [];
8857.
    
8858.
            for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8859.
                for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8860.
                    a.push( {
8861.
                        row:    rows[idx][i],
8862.
                        column: columns[idx][j]
8863.
                    } );
8864.
                }
8865.
            }
8866.
    
8867.
            return a;
8868.
        }, 1 );
8869.
    
8870.
        // There is currently only one extension which uses a cell selector extension
8871.
        // It is a _major_ performance drag to run this if it isn't needed, so this is
8872.
        // an extension specific check at the moment
8873.
        var cells = opts && opts.selected ?
8874.
            this.cells( cellsNoOpts, opts ) :
8875.
            cellsNoOpts;
8876.
    
8877.
        $.extend( cells.selector, {
8878.
            cols: columnSelector,
8879.
            rows: rowSelector,
8880.
            opts: opts
8881.
        } );
8882.
    
8883.
        return cells;
8884.
    } );
8885.
    
8886.
    
8887.
    _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8888.
        return this.iterator( 'cell', function ( settings, row, column ) {
8889.
            var data = settings.aoData[ row ];
8890.
    
8891.
            return data && data.anCells ?
8892.
                data.anCells[ column ] :
8893.
                undefined;
8894.
        }, 1 );
8895.
    } );
8896.
    
8897.
    
8898.
    _api_register( 'cells().data()', function () {
8899.
        return this.iterator( 'cell', function ( settings, row, column ) {
8900.
            return _fnGetCellData( settings, row, column );
8901.
        }, 1 );
8902.
    } );
8903.
    
8904.
    
8905.
    _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8906.
        type = type === 'search' ? '_aFilterData' : '_aSortData';
8907.
    
8908.
        return this.iterator( 'cell', function ( settings, row, column ) {
8909.
            return settings.aoData[ row ][ type ][ column ];
8910.
        }, 1 );
8911.
    } );
8912.
    
8913.
    
8914.
    _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8915.
        return this.iterator( 'cell', function ( settings, row, column ) {
8916.
            return _fnGetCellData( settings, row, column, type );
8917.
        }, 1 );
8918.
    } );
8919.
    
8920.
    
8921.
    _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8922.
        return this.iterator( 'cell', function ( settings, row, column ) {
8923.
            return {
8924.
                row: row,
8925.
                column: column,
8926.
                columnVisible: _fnColumnIndexToVisible( settings, column )
8927.
            };
8928.
        }, 1 );
8929.
    } );
8930.
    
8931.
    
8932.
    _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8933.
        return this.iterator( 'cell', function ( settings, row, column ) {
8934.
            _fnInvalidate( settings, row, src, column );
8935.
        } );
8936.
    } );
8937.
    
8938.
    
8939.
    
8940.
    _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8941.
        return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8942.
    } );
8943.
    
8944.
    
8945.
    _api_register( 'cell().data()', function ( data ) {
8946.
        var ctx = this.context;
8947.
        var cell = this[0];
8948.
    
8949.
        if ( data === undefined ) {
8950.
            // Get
8951.
            return ctx.length && cell.length ?
8952.
                _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8953.
                undefined;
8954.
        }
8955.
    
8956.
        // Set
8957.
        _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8958.
        _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8959.
    
8960.
        return this;
8961.
    } );
8962.
    
8963.
    
8964.
    
8965.
    /**
8966.
     * Get current ordering (sorting) that has been applied to the table.
8967.
     *
8968.
     * @returns {array} 2D array containing the sorting information for the first
8969.
     *   table in the current context. Each element in the parent array represents
8970.
     *   a column being sorted upon (i.e. multi-sorting with two columns would have
8971.
     *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8972.
     *   the column index that the sorting condition applies to, the second is the
8973.
     *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
8974.
     *   index of the sorting order from the `column.sorting` initialisation array.
8975.
     *//**
8976.
     * Set the ordering for the table.
8977.
     *
8978.
     * @param {integer} order Column index to sort upon.
8979.
     * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8980.
     * @returns {DataTables.Api} this
8981.
     *//**
8982.
     * Set the ordering for the table.
8983.
     *
8984.
     * @param {array} order 1D array of sorting information to be applied.
8985.
     * @param {array} [...] Optional additional sorting conditions
8986.
     * @returns {DataTables.Api} this
8987.
     *//**
8988.
     * Set the ordering for the table.
8989.
     *
8990.
     * @param {array} order 2D array of sorting information to be applied.
8991.
     * @returns {DataTables.Api} this
8992.
     */
8993.
    _api_register( 'order()', function ( order, dir ) {
8994.
        var ctx = this.context;
8995.
    
8996.
        if ( order === undefined ) {
8997.
            // get
8998.
            return ctx.length !== 0 ?
8999.
                ctx[0].aaSorting :
9000.
                undefined;
9001.
        }
9002.
    
9003.
        // set
9004.
        if ( typeof order === 'number' ) {
9005.
            // Simple column / direction passed in
9006.
            order = [ [ order, dir ] ];
9007.
        }
9008.
        else if ( order.length && ! $.isArray( order[0] ) ) {
9009.
            // Arguments passed in (list of 1D arrays)
9010.
            order = Array.prototype.slice.call( arguments );
9011.
        }
9012.
        // otherwise a 2D array was passed in
9013.
    
9014.
        return this.iterator( 'table', function ( settings ) {
9015.
            settings.aaSorting = order.slice();
9016.
        } );
9017.
    } );
9018.
    
9019.
    
9020.
    /**
9021.
     * Attach a sort listener to an element for a given column
9022.
     *
9023.
     * @param {node|jQuery|string} node Identifier for the element(s) to attach the
9024.
     *   listener to. This can take the form of a single DOM node, a jQuery
9025.
     *   collection of nodes or a jQuery selector which will identify the node(s).
9026.
     * @param {integer} column the column that a click on this node will sort on
9027.
     * @param {function} [callback] callback function when sort is run
9028.
     * @returns {DataTables.Api} this
9029.
     */
9030.
    _api_register( 'order.listener()', function ( node, column, callback ) {
9031.
        return this.iterator( 'table', function ( settings ) {
9032.
            _fnSortAttachListener( settings, node, column, callback );
9033.
        } );
9034.
    } );
9035.
    
9036.
    
9037.
    _api_register( 'order.fixed()', function ( set ) {
9038.
        if ( ! set ) {
9039.
            var ctx = this.context;
9040.
            var fixed = ctx.length ?
9041.
                ctx[0].aaSortingFixed :
9042.
                undefined;
9043.
    
9044.
            return $.isArray( fixed ) ?
9045.
                { pre: fixed } :
9046.
                fixed;
9047.
        }
9048.
    
9049.
        return this.iterator( 'table', function ( settings ) {
9050.
            settings.aaSortingFixed = $.extend( true, {}, set );
9051.
        } );
9052.
    } );
9053.
    
9054.
    
9055.
    // Order by the selected column(s)
9056.
    _api_register( [
9057.
        'columns().order()',
9058.
        'column().order()'
9059.
    ], function ( dir ) {
9060.
        var that = this;
9061.
    
9062.
        return this.iterator( 'table', function ( settings, i ) {
9063.
            var sort = [];
9064.
    
9065.
            $.each( that[i], function (j, col) {
9066.
                sort.push( [ col, dir ] );
9067.
            } );
9068.
    
9069.
            settings.aaSorting = sort;
9070.
        } );
9071.
    } );
9072.
    
9073.
    
9074.
    
9075.
    _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
9076.
        var ctx = this.context;
9077.
    
9078.
        if ( input === undefined ) {
9079.
            // get
9080.
            return ctx.length !== 0 ?
9081.
                ctx[0].oPreviousSearch.sSearch :
9082.
                undefined;
9083.
        }
9084.
    
9085.
        // set
9086.
        return this.iterator( 'table', function ( settings ) {
9087.
            if ( ! settings.oFeatures.bFilter ) {
9088.
                return;
9089.
            }
9090.
    
9091.
            _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
9092.
                "sSearch": input+"",
9093.
                "bRegex":  regex === null ? false : regex,
9094.
                "bSmart":  smart === null ? true  : smart,
9095.
                "bCaseInsensitive": caseInsen === null ? true : caseInsen
9096.
            } ), 1 );
9097.
        } );
9098.
    } );
9099.
    
9100.
    
9101.
    _api_registerPlural(
9102.
        'columns().search()',
9103.
        'column().search()',
9104.
        function ( input, regex, smart, caseInsen ) {
9105.
            return this.iterator( 'column', function ( settings, column ) {
9106.
                var preSearch = settings.aoPreSearchCols;
9107.
    
9108.
                if ( input === undefined ) {
9109.
                    // get
9110.
                    return preSearch[ column ].sSearch;
9111.
                }
9112.
    
9113.
                // set
9114.
                if ( ! settings.oFeatures.bFilter ) {
9115.
                    return;
9116.
                }
9117.
    
9118.
                $.extend( preSearch[ column ], {
9119.
                    "sSearch": input+"",
9120.
                    "bRegex":  regex === null ? false : regex,
9121.
                    "bSmart":  smart === null ? true  : smart,
9122.
                    "bCaseInsensitive": caseInsen === null ? true : caseInsen
9123.
                } );
9124.
    
9125.
                _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
9126.
            } );
9127.
        }
9128.
    );
9129.
    
9130.
    /*
9131.
     * State API methods
9132.
     */
9133.
    
9134.
    _api_register( 'state()', function () {
9135.
        return this.context.length ?
9136.
            this.context[0].oSavedState :
9137.
            null;
9138.
    } );
9139.
    
9140.
    
9141.
    _api_register( 'state.clear()', function () {
9142.
        return this.iterator( 'table', function ( settings ) {
9143.
            // Save an empty object
9144.
            settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
9145.
        } );
9146.
    } );
9147.
    
9148.
    
9149.
    _api_register( 'state.loaded()', function () {
9150.
        return this.context.length ?
9151.
            this.context[0].oLoadedState :
9152.
            null;
9153.
    } );
9154.
    
9155.
    
9156.
    _api_register( 'state.save()', function () {
9157.
        return this.iterator( 'table', function ( settings ) {
9158.
            _fnSaveState( settings );
9159.
        } );
9160.
    } );
9161.
    
9162.
    
9163.
    
9164.
    /**
9165.
     * Provide a common method for plug-ins to check the version of DataTables being
9166.
     * used, in order to ensure compatibility.
9167.
     *
9168.
     *  @param {string} version Version string to check for, in the format "X.Y.Z".
9169.
     *    Note that the formats "X" and "X.Y" are also acceptable.
9170.
     *  @returns {boolean} true if this version of DataTables is greater or equal to
9171.
     *    the required version, or false if this version of DataTales is not
9172.
     *    suitable
9173.
     *  @static
9174.
     *  @dtopt API-Static
9175.
     *
9176.
     *  @example
9177.
     *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
9178.
     */
9179.
    DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
9180.
    {
9181.
        var aThis = DataTable.version.split('.');
9182.
        var aThat = version.split('.');
9183.
        var iThis, iThat;
9184.
    
9185.
        for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
9186.
            iThis = parseInt( aThis[i], 10 ) || 0;
9187.
            iThat = parseInt( aThat[i], 10 ) || 0;
9188.
    
9189.
            // Parts are the same, keep comparing
9190.
            if (iThis === iThat) {
9191.
                continue;
9192.
            }
9193.
    
9194.
            // Parts are different, return immediately
9195.
            return iThis > iThat;
9196.
        }
9197.
    
9198.
        return true;
9199.
    };
9200.
    
9201.
    
9202.
    /**
9203.
     * Check if a `<table>` node is a DataTable table already or not.
9204.
     *
9205.
     *  @param {node|jquery|string} table Table node, jQuery object or jQuery
9206.
     *      selector for the table to test. Note that if more than more than one
9207.
     *      table is passed on, only the first will be checked
9208.
     *  @returns {boolean} true the table given is a DataTable, or false otherwise
9209.
     *  @static
9210.
     *  @dtopt API-Static
9211.
     *
9212.
     *  @example
9213.
     *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
9214.
     *      $('#example').dataTable();
9215.
     *    }
9216.
     */
9217.
    DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
9218.
    {
9219.
        var t = $(table).get(0);
9220.
        var is = false;
9221.
    
9222.
        if ( table instanceof DataTable.Api ) {
9223.
            return true;
9224.
        }
9225.
    
9226.
        $.each( DataTable.settings, function (i, o) {
9227.
            var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
9228.
            var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
9229.
    
9230.
            if ( o.nTable === t || head === t || foot === t ) {
9231.
                is = true;
9232.
            }
9233.
        } );
9234.
    
9235.
        return is;
9236.
    };
9237.
    
9238.
    
9239.
    /**
9240.
     * Get all DataTable tables that have been initialised - optionally you can
9241.
     * select to get only currently visible tables.
9242.
     *
9243.
     *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
9244.
     *    or visible tables only.
9245.
     *  @returns {array} Array of `table` nodes (not DataTable instances) which are
9246.
     *    DataTables
9247.
     *  @static
9248.
     *  @dtopt API-Static
9249.
     *
9250.
     *  @example
9251.
     *    $.each( $.fn.dataTable.tables(true), function () {
9252.
     *      $(table).DataTable().columns.adjust();
9253.
     *    } );
9254.
     */
9255.
    DataTable.tables = DataTable.fnTables = function ( visible )
9256.
    {
9257.
        var api = false;
9258.
    
9259.
        if ( $.isPlainObject( visible ) ) {
9260.
            api = visible.api;
9261.
            visible = visible.visible;
9262.
        }
9263.
    
9264.
        var a = $.map( DataTable.settings, function (o) {
9265.
            if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
9266.
                return o.nTable;
9267.
            }
9268.
        } );
9269.
    
9270.
        return api ?
9271.
            new _Api( a ) :
9272.
            a;
9273.
    };
9274.
    
9275.
    
9276.
    /**
9277.
     * Convert from camel case parameters to Hungarian notation. This is made public
9278.
     * for the extensions to provide the same ability as DataTables core to accept
9279.
     * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9280.
     * parameters.
9281.
     *
9282.
     *  @param {object} src The model object which holds all parameters that can be
9283.
     *    mapped.
9284.
     *  @param {object} user The object to convert from camel case to Hungarian.
9285.
     *  @param {boolean} force When set to `true`, properties which already have a
9286.
     *    Hungarian value in the `user` object will be overwritten. Otherwise they
9287.
     *    won't be.
9288.
     */
9289.
    DataTable.camelToHungarian = _fnCamelToHungarian;
9290.
    
9291.
    
9292.
    
9293.
    /**
9294.
     *
9295.
     */
9296.
    _api_register( '$()', function ( selector, opts ) {
9297.
        var
9298.
            rows   = this.rows( opts ).nodes(), // Get all rows
9299.
            jqRows = $(rows);
9300.
    
9301.
        return $( [].concat(
9302.
            jqRows.filter( selector ).toArray(),
9303.
            jqRows.find( selector ).toArray()
9304.
        ) );
9305.
    } );
9306.
    
9307.
    
9308.
    // jQuery functions to operate on the tables
9309.
    $.each( [ 'on', 'one', 'off' ], function (i, key) {
9310.
        _api_register( key+'()', function ( /* event, handler */ ) {
9311.
            var args = Array.prototype.slice.call(arguments);
9312.
    
9313.
            // Add the `dt` namespace automatically if it isn't already present
9314.
            args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
9315.
                return ! e.match(/\.dt\b/) ?
9316.
                    e+'.dt' :
9317.
                    e;
9318.
                } ).join( ' ' );
9319.
    
9320.
            var inst = $( this.tables().nodes() );
9321.
            inst[key].apply( inst, args );
9322.
            return this;
9323.
        } );
9324.
    } );
9325.
    
9326.
    
9327.
    _api_register( 'clear()', function () {
9328.
        return this.iterator( 'table', function ( settings ) {
9329.
            _fnClearTable( settings );
9330.
        } );
9331.
    } );
9332.
    
9333.
    
9334.
    _api_register( 'settings()', function () {
9335.
        return new _Api( this.context, this.context );
9336.
    } );
9337.
    
9338.
    
9339.
    _api_register( 'init()', function () {
9340.
        var ctx = this.context;
9341.
        return ctx.length ? ctx[0].oInit : null;
9342.
    } );
9343.
    
9344.
    
9345.
    _api_register( 'data()', function () {
9346.
        return this.iterator( 'table', function ( settings ) {
9347.
            return _pluck( settings.aoData, '_aData' );
9348.
        } ).flatten();
9349.
    } );
9350.
    
9351.
    
9352.
    _api_register( 'destroy()', function ( remove ) {
9353.
        remove = remove || false;
9354.
    
9355.
        return this.iterator( 'table', function ( settings ) {
9356.
            var orig      = settings.nTableWrapper.parentNode;
9357.
            var classes   = settings.oClasses;
9358.
            var table     = settings.nTable;
9359.
            var tbody     = settings.nTBody;
9360.
            var thead     = settings.nTHead;
9361.
            var tfoot     = settings.nTFoot;
9362.
            var jqTable   = $(table);
9363.
            var jqTbody   = $(tbody);
9364.
            var jqWrapper = $(settings.nTableWrapper);
9365.
            var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
9366.
            var i, ien;
9367.
    
9368.
            // Flag to note that the table is currently being destroyed - no action
9369.
            // should be taken
9370.
            settings.bDestroying = true;
9371.
    
9372.
            // Fire off the destroy callbacks for plug-ins etc
9373.
            _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9374.
    
9375.
            // If not being removed from the document, make all columns visible
9376.
            if ( ! remove ) {
9377.
                new _Api( settings ).columns().visible( true );
9378.
            }
9379.
    
9380.
            // Blitz all `DT` namespaced events (these are internal events, the
9381.
            // lowercase, `dt` events are user subscribed and they are responsible
9382.
            // for removing them
9383.
            jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9384.
            $(window).off('.DT-'+settings.sInstance);
9385.
    
9386.
            // When scrolling we had to break the table up - restore it
9387.
            if ( table != thead.parentNode ) {
9388.
                jqTable.children('thead').detach();
9389.
                jqTable.append( thead );
9390.
            }
9391.
    
9392.
            if ( tfoot && table != tfoot.parentNode ) {
9393.
                jqTable.children('tfoot').detach();
9394.
                jqTable.append( tfoot );
9395.
            }
9396.
    
9397.
            settings.aaSorting = [];
9398.
            settings.aaSortingFixed = [];
9399.
            _fnSortingClasses( settings );
9400.
    
9401.
            $( rows ).removeClass( settings.asStripeClasses.join(' ') );
9402.
    
9403.
            $('th, td', thead).removeClass( classes.sSortable+' '+
9404.
                classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9405.
            );
9406.
    
9407.
            // Add the TR elements back into the table in their original order
9408.
            jqTbody.children().detach();
9409.
            jqTbody.append( rows );
9410.
    
9411.
            // Remove the DataTables generated nodes, events and classes
9412.
            var removedMethod = remove ? 'remove' : 'detach';
9413.
            jqTable[ removedMethod ]();
9414.
            jqWrapper[ removedMethod ]();
9415.
    
9416.
            // If we need to reattach the table to the document
9417.
            if ( ! remove && orig ) {
9418.
                // insertBefore acts like appendChild if !arg[1]
9419.
                orig.insertBefore( table, settings.nTableReinsertBefore );
9420.
    
9421.
                // Restore the width of the original table - was read from the style property,
9422.
                // so we can restore directly to that
9423.
                jqTable
9424.
                    .css( 'width', settings.sDestroyWidth )
9425.
                    .removeClass( classes.sTable );
9426.
    
9427.
                // If the were originally stripe classes - then we add them back here.
9428.
                // Note this is not fool proof (for example if not all rows had stripe
9429.
                // classes - but it's a good effort without getting carried away
9430.
                ien = settings.asDestroyStripes.length;
9431.
    
9432.
                if ( ien ) {
9433.
                    jqTbody.children().each( function (i) {
9434.
                        $(this).addClass( settings.asDestroyStripes[i % ien] );
9435.
                    } );
9436.
                }
9437.
            }
9438.
    
9439.
            /* Remove the settings object from the settings array */
9440.
            var idx = $.inArray( settings, DataTable.settings );
9441.
            if ( idx !== -1 ) {
9442.
                DataTable.settings.splice( idx, 1 );
9443.
            }
9444.
        } );
9445.
    } );
9446.
    
9447.
    
9448.
    // Add the `every()` method for rows, columns and cells in a compact form
9449.
    $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9450.
        _api_register( type+'s().every()', function ( fn ) {
9451.
            var opts = this.selector.opts;
9452.
            var api = this;
9453.
    
9454.
            return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9455.
                // Rows and columns:
9456.
                //  arg1 - index
9457.
                //  arg2 - table counter
9458.
                //  arg3 - loop counter
9459.
                //  arg4 - undefined
9460.
                // Cells:
9461.
                //  arg1 - row index
9462.
                //  arg2 - column index
9463.
                //  arg3 - table counter
9464.
                //  arg4 - loop counter
9465.
                fn.call(
9466.
                    api[ type ](
9467.
                        arg1,
9468.
                        type==='cell' ? arg2 : opts,
9469.
                        type==='cell' ? opts : undefined
9470.
                    ),
9471.
                    arg1, arg2, arg3, arg4
9472.
                );
9473.
            } );
9474.
        } );
9475.
    } );
9476.
    
9477.
    
9478.
    // i18n method for extensions to be able to use the language object from the
9479.
    // DataTable
9480.
    _api_register( 'i18n()', function ( token, def, plural ) {
9481.
        var ctx = this.context[0];
9482.
        var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9483.
    
9484.
        if ( resolved === undefined ) {
9485.
            resolved = def;
9486.
        }
9487.
    
9488.
        if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9489.
            resolved = resolved[ plural ] !== undefined ?
9490.
                resolved[ plural ] :
9491.
                resolved._;
9492.
        }
9493.
    
9494.
        return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9495.
    } );
9496.
    /**
9497.
     * Version string for plug-ins to check compatibility. Allowed format is
9498.
     * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9499.
     * only for non-release builds. See http://semver.org/ for more information.
9500.
     *  @member
9501.
     *  @type string
9502.
     *  @default Version number
9503.
     */
9504.
    DataTable.version = "1.10.21";
9505.
 
9506.
    /**
9507.
     * Private data store, containing all of the settings objects that are
9508.
     * created for the tables on a given page.
9509.
     *
9510.
     * Note that the `DataTable.settings` object is aliased to
9511.
     * `jQuery.fn.dataTableExt` through which it may be accessed and
9512.
     * manipulated, or `jQuery.fn.dataTable.settings`.
9513.
     *  @member
9514.
     *  @type array
9515.
     *  @default []
9516.
     *  @private
9517.
     */
9518.
    DataTable.settings = [];
9519.
 
9520.
    /**
9521.
     * Object models container, for the various models that DataTables has
9522.
     * available to it. These models define the objects that are used to hold
9523.
     * the active state and configuration of the table.
9524.
     *  @namespace
9525.
     */
9526.
    DataTable.models = {};
9527.
    
9528.
    
9529.
    
9530.
    /**
9531.
     * Template object for the way in which DataTables holds information about
9532.
     * search information for the global filter and individual column filters.
9533.
     *  @namespace
9534.
     */
9535.
    DataTable.models.oSearch = {
9536.
        /**
9537.
         * Flag to indicate if the filtering should be case insensitive or not
9538.
         *  @type boolean
9539.
         *  @default true
9540.
         */
9541.
        "bCaseInsensitive": true,
9542.
    
9543.
        /**
9544.
         * Applied search term
9545.
         *  @type string
9546.
         *  @default <i>Empty string</i>
9547.
         */
9548.
        "sSearch": "",
9549.
    
9550.
        /**
9551.
         * Flag to indicate if the search term should be interpreted as a
9552.
         * regular expression (true) or not (false) and therefore and special
9553.
         * regex characters escaped.
9554.
         *  @type boolean
9555.
         *  @default false
9556.
         */
9557.
        "bRegex": false,
9558.
    
9559.
        /**
9560.
         * Flag to indicate if DataTables is to use its smart filtering or not.
9561.
         *  @type boolean
9562.
         *  @default true
9563.
         */
9564.
        "bSmart": true
9565.
    };
9566.
    
9567.
    
9568.
    
9569.
    
9570.
    /**
9571.
     * Template object for the way in which DataTables holds information about
9572.
     * each individual row. This is the object format used for the settings
9573.
     * aoData array.
9574.
     *  @namespace
9575.
     */
9576.
    DataTable.models.oRow = {
9577.
        /**
9578.
         * TR element for the row
9579.
         *  @type node
9580.
         *  @default null
9581.
         */
9582.
        "nTr": null,
9583.
    
9584.
        /**
9585.
         * Array of TD elements for each row. This is null until the row has been
9586.
         * created.
9587.
         *  @type array nodes
9588.
         *  @default []
9589.
         */
9590.
        "anCells": null,
9591.
    
9592.
        /**
9593.
         * Data object from the original data source for the row. This is either
9594.
         * an array if using the traditional form of DataTables, or an object if
9595.
         * using mData options. The exact type will depend on the passed in
9596.
         * data from the data source, or will be an array if using DOM a data
9597.
         * source.
9598.
         *  @type array|object
9599.
         *  @default []
9600.
         */
9601.
        "_aData": [],
9602.
    
9603.
        /**
9604.
         * Sorting data cache - this array is ostensibly the same length as the
9605.
         * number of columns (although each index is generated only as it is
9606.
         * needed), and holds the data that is used for sorting each column in the
9607.
         * row. We do this cache generation at the start of the sort in order that
9608.
         * the formatting of the sort data need be done only once for each cell
9609.
         * per sort. This array should not be read from or written to by anything
9610.
         * other than the master sorting methods.
9611.
         *  @type array
9612.
         *  @default null
9613.
         *  @private
9614.
         */
9615.
        "_aSortData": null,
9616.
    
9617.
        /**
9618.
         * Per cell filtering data cache. As per the sort data cache, used to
9619.
         * increase the performance of the filtering in DataTables
9620.
         *  @type array
9621.
         *  @default null
9622.
         *  @private
9623.
         */
9624.
        "_aFilterData": null,
9625.
    
9626.
        /**
9627.
         * Filtering data cache. This is the same as the cell filtering cache, but
9628.
         * in this case a string rather than an array. This is easily computed with
9629.
         * a join on `_aFilterData`, but is provided as a cache so the join isn't
9630.
         * needed on every search (memory traded for performance)
9631.
         *  @type array
9632.
         *  @default null
9633.
         *  @private
9634.
         */
9635.
        "_sFilterRow": null,
9636.
    
9637.
        /**
9638.
         * Cache of the class name that DataTables has applied to the row, so we
9639.
         * can quickly look at this variable rather than needing to do a DOM check
9640.
         * on className for the nTr property.
9641.
         *  @type string
9642.
         *  @default <i>Empty string</i>
9643.
         *  @private
9644.
         */
9645.
        "_sRowStripe": "",
9646.
    
9647.
        /**
9648.
         * Denote if the original data source was from the DOM, or the data source
9649.
         * object. This is used for invalidating data, so DataTables can
9650.
         * automatically read data from the original source, unless uninstructed
9651.
         * otherwise.
9652.
         *  @type string
9653.
         *  @default null
9654.
         *  @private
9655.
         */
9656.
        "src": null,
9657.
    
9658.
        /**
9659.
         * Index in the aoData array. This saves an indexOf lookup when we have the
9660.
         * object, but want to know the index
9661.
         *  @type integer
9662.
         *  @default -1
9663.
         *  @private
9664.
         */
9665.
        "idx": -1
9666.
    };
9667.
    
9668.
    
9669.
    /**
9670.
     * Template object for the column information object in DataTables. This object
9671.
     * is held in the settings aoColumns array and contains all the information that
9672.
     * DataTables needs about each individual column.
9673.
     *
9674.
     * Note that this object is related to {@link DataTable.defaults.column}
9675.
     * but this one is the internal data store for DataTables's cache of columns.
9676.
     * It should NOT be manipulated outside of DataTables. Any configuration should
9677.
     * be done through the initialisation options.
9678.
     *  @namespace
9679.
     */
9680.
    DataTable.models.oColumn = {
9681.
        /**
9682.
         * Column index. This could be worked out on-the-fly with $.inArray, but it
9683.
         * is faster to just hold it as a variable
9684.
         *  @type integer
9685.
         *  @default null
9686.
         */
9687.
        "idx": null,
9688.
    
9689.
        /**
9690.
         * A list of the columns that sorting should occur on when this column
9691.
         * is sorted. That this property is an array allows multi-column sorting
9692.
         * to be defined for a column (for example first name / last name columns
9693.
         * would benefit from this). The values are integers pointing to the
9694.
         * columns to be sorted on (typically it will be a single integer pointing
9695.
         * at itself, but that doesn't need to be the case).
9696.
         *  @type array
9697.
         */
9698.
        "aDataSort": null,
9699.
    
9700.
        /**
9701.
         * Define the sorting directions that are applied to the column, in sequence
9702.
         * as the column is repeatedly sorted upon - i.e. the first value is used
9703.
         * as the sorting direction when the column if first sorted (clicked on).
9704.
         * Sort it again (click again) and it will move on to the next index.
9705.
         * Repeat until loop.
9706.
         *  @type array
9707.
         */
9708.
        "asSorting": null,
9709.
    
9710.
        /**
9711.
         * Flag to indicate if the column is searchable, and thus should be included
9712.
         * in the filtering or not.
9713.
         *  @type boolean
9714.
         */
9715.
        "bSearchable": null,
9716.
    
9717.
        /**
9718.
         * Flag to indicate if the column is sortable or not.
9719.
         *  @type boolean
9720.
         */
9721.
        "bSortable": null,
9722.
    
9723.
        /**
9724.
         * Flag to indicate if the column is currently visible in the table or not
9725.
         *  @type boolean
9726.
         */
9727.
        "bVisible": null,
9728.
    
9729.
        /**
9730.
         * Store for manual type assignment using the `column.type` option. This
9731.
         * is held in store so we can manipulate the column's `sType` property.
9732.
         *  @type string
9733.
         *  @default null
9734.
         *  @private
9735.
         */
9736.
        "_sManualType": null,
9737.
    
9738.
        /**
9739.
         * Flag to indicate if HTML5 data attributes should be used as the data
9740.
         * source for filtering or sorting. True is either are.
9741.
         *  @type boolean
9742.
         *  @default false
9743.
         *  @private
9744.
         */
9745.
        "_bAttrSrc": false,
9746.
    
9747.
        /**
9748.
         * Developer definable function that is called whenever a cell is created (Ajax source,
9749.
         * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9750.
         * allowing you to modify the DOM element (add background colour for example) when the
9751.
         * element is available.
9752.
         *  @type function
9753.
         *  @param {element} nTd The TD node that has been created
9754.
         *  @param {*} sData The Data for the cell
9755.
         *  @param {array|object} oData The data for the whole row
9756.
         *  @param {int} iRow The row index for the aoData data store
9757.
         *  @default null
9758.
         */
9759.
        "fnCreatedCell": null,
9760.
    
9761.
        /**
9762.
         * Function to get data from a cell in a column. You should <b>never</b>
9763.
         * access data directly through _aData internally in DataTables - always use
9764.
         * the method attached to this property. It allows mData to function as
9765.
         * required. This function is automatically assigned by the column
9766.
         * initialisation method
9767.
         *  @type function
9768.
         *  @param {array|object} oData The data array/object for the array
9769.
         *    (i.e. aoData[]._aData)
9770.
         *  @param {string} sSpecific The specific data type you want to get -
9771.
         *    'display', 'type' 'filter' 'sort'
9772.
         *  @returns {*} The data for the cell from the given row's data
9773.
         *  @default null
9774.
         */
9775.
        "fnGetData": null,
9776.
    
9777.
        /**
9778.
         * Function to set data for a cell in the column. You should <b>never</b>
9779.
         * set the data directly to _aData internally in DataTables - always use
9780.
         * this method. It allows mData to function as required. This function
9781.
         * is automatically assigned by the column initialisation method
9782.
         *  @type function
9783.
         *  @param {array|object} oData The data array/object for the array
9784.
         *    (i.e. aoData[]._aData)
9785.
         *  @param {*} sValue Value to set
9786.
         *  @default null
9787.
         */
9788.
        "fnSetData": null,
9789.
    
9790.
        /**
9791.
         * Property to read the value for the cells in the column from the data
9792.
         * source array / object. If null, then the default content is used, if a
9793.
         * function is given then the return from the function is used.
9794.
         *  @type function|int|string|null
9795.
         *  @default null
9796.
         */
9797.
        "mData": null,
9798.
    
9799.
        /**
9800.
         * Partner property to mData which is used (only when defined) to get
9801.
         * the data - i.e. it is basically the same as mData, but without the
9802.
         * 'set' option, and also the data fed to it is the result from mData.
9803.
         * This is the rendering method to match the data method of mData.
9804.
         *  @type function|int|string|null
9805.
         *  @default null
9806.
         */
9807.
        "mRender": null,
9808.
    
9809.
        /**
9810.
         * Unique header TH/TD element for this column - this is what the sorting
9811.
         * listener is attached to (if sorting is enabled.)
9812.
         *  @type node
9813.
         *  @default null
9814.
         */
9815.
        "nTh": null,
9816.
    
9817.
        /**
9818.
         * Unique footer TH/TD element for this column (if there is one). Not used
9819.
         * in DataTables as such, but can be used for plug-ins to reference the
9820.
         * footer for each column.
9821.
         *  @type node
9822.
         *  @default null
9823.
         */
9824.
        "nTf": null,
9825.
    
9826.
        /**
9827.
         * The class to apply to all TD elements in the table's TBODY for the column
9828.
         *  @type string
9829.
         *  @default null
9830.
         */
9831.
        "sClass": null,
9832.
    
9833.
        /**
9834.
         * When DataTables calculates the column widths to assign to each column,
9835.
         * it finds the longest string in each column and then constructs a
9836.
         * temporary table and reads the widths from that. The problem with this
9837.
         * is that "mmm" is much wider then "iiii", but the latter is a longer
9838.
         * string - thus the calculation can go wrong (doing it properly and putting
9839.
         * it into an DOM object and measuring that is horribly(!) slow). Thus as
9840.
         * a "work around" we provide this option. It will append its value to the
9841.
         * text that is found to be the longest string for the column - i.e. padding.
9842.
         *  @type string
9843.
         */
9844.
        "sContentPadding": null,
9845.
    
9846.
        /**
9847.
         * Allows a default value to be given for a column's data, and will be used
9848.
         * whenever a null data source is encountered (this can be because mData
9849.
         * is set to null, or because the data source itself is null).
9850.
         *  @type string
9851.
         *  @default null
9852.
         */
9853.
        "sDefaultContent": null,
9854.
    
9855.
        /**
9856.
         * Name for the column, allowing reference to the column by name as well as
9857.
         * by index (needs a lookup to work by name).
9858.
         *  @type string
9859.
         */
9860.
        "sName": null,
9861.
    
9862.
        /**
9863.
         * Custom sorting data type - defines which of the available plug-ins in
9864.
         * afnSortData the custom sorting will use - if any is defined.
9865.
         *  @type string
9866.
         *  @default std
9867.
         */
9868.
        "sSortDataType": 'std',
9869.
    
9870.
        /**
9871.
         * Class to be applied to the header element when sorting on this column
9872.
         *  @type string
9873.
         *  @default null
9874.
         */
9875.
        "sSortingClass": null,
9876.
    
9877.
        /**
9878.
         * Class to be applied to the header element when sorting on this column -
9879.
         * when jQuery UI theming is used.
9880.
         *  @type string
9881.
         *  @default null
9882.
         */
9883.
        "sSortingClassJUI": null,
9884.
    
9885.
        /**
9886.
         * Title of the column - what is seen in the TH element (nTh).
9887.
         *  @type string
9888.
         */
9889.
        "sTitle": null,
9890.
    
9891.
        /**
9892.
         * Column sorting and filtering type
9893.
         *  @type string
9894.
         *  @default null
9895.
         */
9896.
        "sType": null,
9897.
    
9898.
        /**
9899.
         * Width of the column
9900.
         *  @type string
9901.
         *  @default null
9902.
         */
9903.
        "sWidth": null,
9904.
    
9905.
        /**
9906.
         * Width of the column when it was first "encountered"
9907.
         *  @type string
9908.
         *  @default null
9909.
         */
9910.
        "sWidthOrig": null
9911.
    };
9912.
    
9913.
    
9914.
    /*
9915.
     * Developer note: The properties of the object below are given in Hungarian
9916.
     * notation, that was used as the interface for DataTables prior to v1.10, however
9917.
     * from v1.10 onwards the primary interface is camel case. In order to avoid
9918.
     * breaking backwards compatibility utterly with this change, the Hungarian
9919.
     * version is still, internally the primary interface, but is is not documented
9920.
     * - hence the @name tags in each doc comment. This allows a Javascript function
9921.
     * to create a map from Hungarian notation to camel case (going the other direction
9922.
     * would require each property to be listed, which would at around 3K to the size
9923.
     * of DataTables, while this method is about a 0.5K hit.
9924.
     *
9925.
     * Ultimately this does pave the way for Hungarian notation to be dropped
9926.
     * completely, but that is a massive amount of work and will break current
9927.
     * installs (therefore is on-hold until v2).
9928.
     */
9929.
    
9930.
    /**
9931.
     * Initialisation options that can be given to DataTables at initialisation
9932.
     * time.
9933.
     *  @namespace
9934.
     */
9935.
    DataTable.defaults = {
9936.
        /**
9937.
         * An array of data to use for the table, passed in at initialisation which
9938.
         * will be used in preference to any data which is already in the DOM. This is
9939.
         * particularly useful for constructing tables purely in Javascript, for
9940.
         * example with a custom Ajax call.
9941.
         *  @type array
9942.
         *  @default null
9943.
         *
9944.
         *  @dtopt Option
9945.
         *  @name DataTable.defaults.data
9946.
         *
9947.
         *  @example
9948.
         *    // Using a 2D array data source
9949.
         *    $(document).ready( function () {
9950.
         *      $('#example').dataTable( {
9951.
         *        "data": [
9952.
         *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9953.
         *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9954.
         *        ],
9955.
         *        "columns": [
9956.
         *          { "title": "Engine" },
9957.
         *          { "title": "Browser" },
9958.
         *          { "title": "Platform" },
9959.
         *          { "title": "Version" },
9960.
         *          { "title": "Grade" }
9961.
         *        ]
9962.
         *      } );
9963.
         *    } );
9964.
         *
9965.
         *  @example
9966.
         *    // Using an array of objects as a data source (`data`)
9967.
         *    $(document).ready( function () {
9968.
         *      $('#example').dataTable( {
9969.
         *        "data": [
9970.
         *          {
9971.
         *            "engine":   "Trident",
9972.
         *            "browser":  "Internet Explorer 4.0",
9973.
         *            "platform": "Win 95+",
9974.
         *            "version":  4,
9975.
         *            "grade":    "X"
9976.
         *          },
9977.
         *          {
9978.
         *            "engine":   "Trident",
9979.
         *            "browser":  "Internet Explorer 5.0",
9980.
         *            "platform": "Win 95+",
9981.
         *            "version":  5,
9982.
         *            "grade":    "C"
9983.
         *          }
9984.
         *        ],
9985.
         *        "columns": [
9986.
         *          { "title": "Engine",   "data": "engine" },
9987.
         *          { "title": "Browser",  "data": "browser" },
9988.
         *          { "title": "Platform", "data": "platform" },
9989.
         *          { "title": "Version",  "data": "version" },
9990.
         *          { "title": "Grade",    "data": "grade" }
9991.
         *        ]
9992.
         *      } );
9993.
         *    } );
9994.
         */
9995.
        "aaData": null,
9996.
    
9997.
    
9998.
        /**
9999.
         * If ordering is enabled, then DataTables will perform a first pass sort on
10000.
         * initialisation. You can define which column(s) the sort is performed
10001.
         * upon, and the sorting direction, with this variable. The `sorting` array
10002.
         * should contain an array for each column to be sorted initially containing
10003.
         * the column's index and a direction string ('asc' or 'desc').
10004.
         *  @type array
10005.
         *  @default [[0,'asc']]
10006.
         *
10007.
         *  @dtopt Option
10008.
         *  @name DataTable.defaults.order
10009.
         *
10010.
         *  @example
10011.
         *    // Sort by 3rd column first, and then 4th column
10012.
         *    $(document).ready( function() {
10013.
         *      $('#example').dataTable( {
10014.
         *        "order": [[2,'asc'], [3,'desc']]
10015.
         *      } );
10016.
         *    } );
10017.
         *
10018.
         *    // No initial sorting
10019.
         *    $(document).ready( function() {
10020.
         *      $('#example').dataTable( {
10021.
         *        "order": []
10022.
         *      } );
10023.
         *    } );
10024.
         */
10025.
        "aaSorting": [[0,'asc']],
10026.
    
10027.
    
10028.
        /**
10029.
         * This parameter is basically identical to the `sorting` parameter, but
10030.
         * cannot be overridden by user interaction with the table. What this means
10031.
         * is that you could have a column (visible or hidden) which the sorting
10032.
         * will always be forced on first - any sorting after that (from the user)
10033.
         * will then be performed as required. This can be useful for grouping rows
10034.
         * together.
10035.
         *  @type array
10036.
         *  @default null
10037.
         *
10038.
         *  @dtopt Option
10039.
         *  @name DataTable.defaults.orderFixed
10040.
         *
10041.
         *  @example
10042.
         *    $(document).ready( function() {
10043.
         *      $('#example').dataTable( {
10044.
         *        "orderFixed": [[0,'asc']]
10045.
         *      } );
10046.
         *    } )
10047.
         */
10048.
        "aaSortingFixed": [],
10049.
    
10050.
    
10051.
        /**
10052.
         * DataTables can be instructed to load data to display in the table from a
10053.
         * Ajax source. This option defines how that Ajax call is made and where to.
10054.
         *
10055.
         * The `ajax` property has three different modes of operation, depending on
10056.
         * how it is defined. These are:
10057.
         *
10058.
         * * `string` - Set the URL from where the data should be loaded from.
10059.
         * * `object` - Define properties for `jQuery.ajax`.
10060.
         * * `function` - Custom data get function
10061.
         *
10062.
         * `string`
10063.
         * --------
10064.
         *
10065.
         * As a string, the `ajax` property simply defines the URL from which
10066.
         * DataTables will load data.
10067.
         *
10068.
         * `object`
10069.
         * --------
10070.
         *
10071.
         * As an object, the parameters in the object are passed to
10072.
         * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
10073.
         * of the Ajax request. DataTables has a number of default parameters which
10074.
         * you can override using this option. Please refer to the jQuery
10075.
         * documentation for a full description of the options available, although
10076.
         * the following parameters provide additional options in DataTables or
10077.
         * require special consideration:
10078.
         *
10079.
         * * `data` - As with jQuery, `data` can be provided as an object, but it
10080.
         *   can also be used as a function to manipulate the data DataTables sends
10081.
         *   to the server. The function takes a single parameter, an object of
10082.
         *   parameters with the values that DataTables has readied for sending. An
10083.
         *   object may be returned which will be merged into the DataTables
10084.
         *   defaults, or you can add the items to the object that was passed in and
10085.
         *   not return anything from the function. This supersedes `fnServerParams`
10086.
         *   from DataTables 1.9-.
10087.
         *
10088.
         * * `dataSrc` - By default DataTables will look for the property `data` (or
10089.
         *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
10090.
         *   from an Ajax source or for server-side processing - this parameter
10091.
         *   allows that property to be changed. You can use Javascript dotted
10092.
         *   object notation to get a data source for multiple levels of nesting, or
10093.
         *   it my be used as a function. As a function it takes a single parameter,
10094.
         *   the JSON returned from the server, which can be manipulated as
10095.
         *   required, with the returned value being that used by DataTables as the
10096.
         *   data source for the table. This supersedes `sAjaxDataProp` from
10097.
         *   DataTables 1.9-.
10098.
         *
10099.
         * * `success` - Should not be overridden it is used internally in
10100.
         *   DataTables. To manipulate / transform the data returned by the server
10101.
         *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
10102.
         *
10103.
         * `function`
10104.
         * ----------
10105.
         *
10106.
         * As a function, making the Ajax call is left up to yourself allowing
10107.
         * complete control of the Ajax request. Indeed, if desired, a method other
10108.
         * than Ajax could be used to obtain the required data, such as Web storage
10109.
         * or an AIR database.
10110.
         *
10111.
         * The function is given four parameters and no return is required. The
10112.
         * parameters are:
10113.
         *
10114.
         * 1. _object_ - Data to send to the server
10115.
         * 2. _function_ - Callback function that must be executed when the required
10116.
         *    data has been obtained. That data should be passed into the callback
10117.
         *    as the only parameter
10118.
         * 3. _object_ - DataTables settings object for the table
10119.
         *
10120.
         * Note that this supersedes `fnServerData` from DataTables 1.9-.
10121.
         *
10122.
         *  @type string|object|function
10123.
         *  @default null
10124.
         *
10125.
         *  @dtopt Option
10126.
         *  @name DataTable.defaults.ajax
10127.
         *  @since 1.10.0
10128.
         *
10129.
         * @example
10130.
         *   // Get JSON data from a file via Ajax.
10131.
         *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
10132.
         *   $('#example').dataTable( {
10133.
         *     "ajax": "data.json"
10134.
         *   } );
10135.
         *
10136.
         * @example
10137.
         *   // Get JSON data from a file via Ajax, using `dataSrc` to change
10138.
         *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
10139.
         *   $('#example').dataTable( {
10140.
         *     "ajax": {
10141.
         *       "url": "data.json",
10142.
         *       "dataSrc": "tableData"
10143.
         *     }
10144.
         *   } );
10145.
         *
10146.
         * @example
10147.
         *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
10148.
         *   // from a plain array rather than an array in an object
10149.
         *   $('#example').dataTable( {
10150.
         *     "ajax": {
10151.
         *       "url": "data.json",
10152.
         *       "dataSrc": ""
10153.
         *     }
10154.
         *   } );
10155.
         *
10156.
         * @example
10157.
         *   // Manipulate the data returned from the server - add a link to data
10158.
         *   // (note this can, should, be done using `render` for the column - this
10159.
         *   // is just a simple example of how the data can be manipulated).
10160.
         *   $('#example').dataTable( {
10161.
         *     "ajax": {
10162.
         *       "url": "data.json",
10163.
         *       "dataSrc": function ( json ) {
10164.
         *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
10165.
         *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
10166.
         *         }
10167.
         *         return json;
10168.
         *       }
10169.
         *     }
10170.
         *   } );
10171.
         *
10172.
         * @example
10173.
         *   // Add data to the request
10174.
         *   $('#example').dataTable( {
10175.
         *     "ajax": {
10176.
         *       "url": "data.json",
10177.
         *       "data": function ( d ) {
10178.
         *         return {
10179.
         *           "extra_search": $('#extra').val()
10180.
         *         };
10181.
         *       }
10182.
         *     }
10183.
         *   } );
10184.
         *
10185.
         * @example
10186.
         *   // Send request as POST
10187.
         *   $('#example').dataTable( {
10188.
         *     "ajax": {
10189.
         *       "url": "data.json",
10190.
         *       "type": "POST"
10191.
         *     }
10192.
         *   } );
10193.
         *
10194.
         * @example
10195.
         *   // Get the data from localStorage (could interface with a form for
10196.
         *   // adding, editing and removing rows).
10197.
         *   $('#example').dataTable( {
10198.
         *     "ajax": function (data, callback, settings) {
10199.
         *       callback(
10200.
         *         JSON.parse( localStorage.getItem('dataTablesData') )
10201.
         *       );
10202.
         *     }
10203.
         *   } );
10204.
         */
10205.
        "ajax": null,
10206.
    
10207.
    
10208.
        /**
10209.
         * This parameter allows you to readily specify the entries in the length drop
10210.
         * down menu that DataTables shows when pagination is enabled. It can be
10211.
         * either a 1D array of options which will be used for both the displayed
10212.
         * option and the value, or a 2D array which will use the array in the first
10213.
         * position as the value, and the array in the second position as the
10214.
         * displayed options (useful for language strings such as 'All').
10215.
         *
10216.
         * Note that the `pageLength` property will be automatically set to the
10217.
         * first value given in this array, unless `pageLength` is also provided.
10218.
         *  @type array
10219.
         *  @default [ 10, 25, 50, 100 ]
10220.
         *
10221.
         *  @dtopt Option
10222.
         *  @name DataTable.defaults.lengthMenu
10223.
         *
10224.
         *  @example
10225.
         *    $(document).ready( function() {
10226.
         *      $('#example').dataTable( {
10227.
         *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
10228.
         *      } );
10229.
         *    } );
10230.
         */
10231.
        "aLengthMenu": [ 10, 25, 50, 100 ],
10232.
    
10233.
    
10234.
        /**
10235.
         * The `columns` option in the initialisation parameter allows you to define
10236.
         * details about the way individual columns behave. For a full list of
10237.
         * column options that can be set, please see
10238.
         * {@link DataTable.defaults.column}. Note that if you use `columns` to
10239.
         * define your columns, you must have an entry in the array for every single
10240.
         * column that you have in your table (these can be null if you don't which
10241.
         * to specify any options).
10242.
         *  @member
10243.
         *
10244.
         *  @name DataTable.defaults.column
10245.
         */
10246.
        "aoColumns": null,
10247.
    
10248.
        /**
10249.
         * Very similar to `columns`, `columnDefs` allows you to target a specific
10250.
         * column, multiple columns, or all columns, using the `targets` property of
10251.
         * each object in the array. This allows great flexibility when creating
10252.
         * tables, as the `columnDefs` arrays can be of any length, targeting the
10253.
         * columns you specifically want. `columnDefs` may use any of the column
10254.
         * options available: {@link DataTable.defaults.column}, but it _must_
10255.
         * have `targets` defined in each object in the array. Values in the `targets`
10256.
         * array may be:
10257.
         *   <ul>
10258.
         *     <li>a string - class name will be matched on the TH for the column</li>
10259.
         *     <li>0 or a positive integer - column index counting from the left</li>
10260.
         *     <li>a negative integer - column index counting from the right</li>
10261.
         *     <li>the string "_all" - all columns (i.e. assign a default)</li>
10262.
         *   </ul>
10263.
         *  @member
10264.
         *
10265.
         *  @name DataTable.defaults.columnDefs
10266.
         */
10267.
        "aoColumnDefs": null,
10268.
    
10269.
    
10270.
        /**
10271.
         * Basically the same as `search`, this parameter defines the individual column
10272.
         * filtering state at initialisation time. The array must be of the same size
10273.
         * as the number of columns, and each element be an object with the parameters
10274.
         * `search` and `escapeRegex` (the latter is optional). 'null' is also
10275.
         * accepted and the default will be used.
10276.
         *  @type array
10277.
         *  @default []
10278.
         *
10279.
         *  @dtopt Option
10280.
         *  @name DataTable.defaults.searchCols
10281.
         *
10282.
         *  @example
10283.
         *    $(document).ready( function() {
10284.
         *      $('#example').dataTable( {
10285.
         *        "searchCols": [
10286.
         *          null,
10287.
         *          { "search": "My filter" },
10288.
         *          null,
10289.
         *          { "search": "^[0-9]", "escapeRegex": false }
10290.
         *        ]
10291.
         *      } );
10292.
         *    } )
10293.
         */
10294.
        "aoSearchCols": [],
10295.
    
10296.
    
10297.
        /**
10298.
         * An array of CSS classes that should be applied to displayed rows. This
10299.
         * array may be of any length, and DataTables will apply each class
10300.
         * sequentially, looping when required.
10301.
         *  @type array
10302.
         *  @default null <i>Will take the values determined by the `oClasses.stripe*`
10303.
         *    options</i>
10304.
         *
10305.
         *  @dtopt Option
10306.
         *  @name DataTable.defaults.stripeClasses
10307.
         *
10308.
         *  @example
10309.
         *    $(document).ready( function() {
10310.
         *      $('#example').dataTable( {
10311.
         *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10312.
         *      } );
10313.
         *    } )
10314.
         */
10315.
        "asStripeClasses": null,
10316.
    
10317.
    
10318.
        /**
10319.
         * Enable or disable automatic column width calculation. This can be disabled
10320.
         * as an optimisation (it takes some time to calculate the widths) if the
10321.
         * tables widths are passed in using `columns`.
10322.
         *  @type boolean
10323.
         *  @default true
10324.
         *
10325.
         *  @dtopt Features
10326.
         *  @name DataTable.defaults.autoWidth
10327.
         *
10328.
         *  @example
10329.
         *    $(document).ready( function () {
10330.
         *      $('#example').dataTable( {
10331.
         *        "autoWidth": false
10332.
         *      } );
10333.
         *    } );
10334.
         */
10335.
        "bAutoWidth": true,
10336.
    
10337.
    
10338.
        /**
10339.
         * Deferred rendering can provide DataTables with a huge speed boost when you
10340.
         * are using an Ajax or JS data source for the table. This option, when set to
10341.
         * true, will cause DataTables to defer the creation of the table elements for
10342.
         * each row until they are needed for a draw - saving a significant amount of
10343.
         * time.
10344.
         *  @type boolean
10345.
         *  @default false
10346.
         *
10347.
         *  @dtopt Features
10348.
         *  @name DataTable.defaults.deferRender
10349.
         *
10350.
         *  @example
10351.
         *    $(document).ready( function() {
10352.
         *      $('#example').dataTable( {
10353.
         *        "ajax": "sources/arrays.txt",
10354.
         *        "deferRender": true
10355.
         *      } );
10356.
         *    } );
10357.
         */
10358.
        "bDeferRender": false,
10359.
    
10360.
    
10361.
        /**
10362.
         * Replace a DataTable which matches the given selector and replace it with
10363.
         * one which has the properties of the new initialisation object passed. If no
10364.
         * table matches the selector, then the new DataTable will be constructed as
10365.
         * per normal.
10366.
         *  @type boolean
10367.
         *  @default false
10368.
         *
10369.
         *  @dtopt Options
10370.
         *  @name DataTable.defaults.destroy
10371.
         *
10372.
         *  @example
10373.
         *    $(document).ready( function() {
10374.
         *      $('#example').dataTable( {
10375.
         *        "srollY": "200px",
10376.
         *        "paginate": false
10377.
         *      } );
10378.
         *
10379.
         *      // Some time later....
10380.
         *      $('#example').dataTable( {
10381.
         *        "filter": false,
10382.
         *        "destroy": true
10383.
         *      } );
10384.
         *    } );
10385.
         */
10386.
        "bDestroy": false,
10387.
    
10388.
    
10389.
        /**
10390.
         * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10391.
         * that it allows the end user to input multiple words (space separated) and
10392.
         * will match a row containing those words, even if not in the order that was
10393.
         * specified (this allow matching across multiple columns). Note that if you
10394.
         * wish to use filtering in DataTables this must remain 'true' - to remove the
10395.
         * default filtering input box and retain filtering abilities, please use
10396.
         * {@link DataTable.defaults.dom}.
10397.
         *  @type boolean
10398.
         *  @default true
10399.
         *
10400.
         *  @dtopt Features
10401.
         *  @name DataTable.defaults.searching
10402.
         *
10403.
         *  @example
10404.
         *    $(document).ready( function () {
10405.
         *      $('#example').dataTable( {
10406.
         *        "searching": false
10407.
         *      } );
10408.
         *    } );
10409.
         */
10410.
        "bFilter": true,
10411.
    
10412.
    
10413.
        /**
10414.
         * Enable or disable the table information display. This shows information
10415.
         * about the data that is currently visible on the page, including information
10416.
         * about filtered data if that action is being performed.
10417.
         *  @type boolean
10418.
         *  @default true
10419.
         *
10420.
         *  @dtopt Features
10421.
         *  @name DataTable.defaults.info
10422.
         *
10423.
         *  @example
10424.
         *    $(document).ready( function () {
10425.
         *      $('#example').dataTable( {
10426.
         *        "info": false
10427.
         *      } );
10428.
         *    } );
10429.
         */
10430.
        "bInfo": true,
10431.
    
10432.
    
10433.
        /**
10434.
         * Allows the end user to select the size of a formatted page from a select
10435.
         * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10436.
         *  @type boolean
10437.
         *  @default true
10438.
         *
10439.
         *  @dtopt Features
10440.
         *  @name DataTable.defaults.lengthChange
10441.
         *
10442.
         *  @example
10443.
         *    $(document).ready( function () {
10444.
         *      $('#example').dataTable( {
10445.
         *        "lengthChange": false
10446.
         *      } );
10447.
         *    } );
10448.
         */
10449.
        "bLengthChange": true,
10450.
    
10451.
    
10452.
        /**
10453.
         * Enable or disable pagination.
10454.
         *  @type boolean
10455.
         *  @default true
10456.
         *
10457.
         *  @dtopt Features
10458.
         *  @name DataTable.defaults.paging
10459.
         *
10460.
         *  @example
10461.
         *    $(document).ready( function () {
10462.
         *      $('#example').dataTable( {
10463.
         *        "paging": false
10464.
         *      } );
10465.
         *    } );
10466.
         */
10467.
        "bPaginate": true,
10468.
    
10469.
    
10470.
        /**
10471.
         * Enable or disable the display of a 'processing' indicator when the table is
10472.
         * being processed (e.g. a sort). This is particularly useful for tables with
10473.
         * large amounts of data where it can take a noticeable amount of time to sort
10474.
         * the entries.
10475.
         *  @type boolean
10476.
         *  @default false
10477.
         *
10478.
         *  @dtopt Features
10479.
         *  @name DataTable.defaults.processing
10480.
         *
10481.
         *  @example
10482.
         *    $(document).ready( function () {
10483.
         *      $('#example').dataTable( {
10484.
         *        "processing": true
10485.
         *      } );
10486.
         *    } );
10487.
         */
10488.
        "bProcessing": false,
10489.
    
10490.
    
10491.
        /**
10492.
         * Retrieve the DataTables object for the given selector. Note that if the
10493.
         * table has already been initialised, this parameter will cause DataTables
10494.
         * to simply return the object that has already been set up - it will not take
10495.
         * account of any changes you might have made to the initialisation object
10496.
         * passed to DataTables (setting this parameter to true is an acknowledgement
10497.
         * that you understand this). `destroy` can be used to reinitialise a table if
10498.
         * you need.
10499.
         *  @type boolean
10500.
         *  @default false
10501.
         *
10502.
         *  @dtopt Options
10503.
         *  @name DataTable.defaults.retrieve
10504.
         *
10505.
         *  @example
10506.
         *    $(document).ready( function() {
10507.
         *      initTable();
10508.
         *      tableActions();
10509.
         *    } );
10510.
         *
10511.
         *    function initTable ()
10512.
         *    {
10513.
         *      return $('#example').dataTable( {
10514.
         *        "scrollY": "200px",
10515.
         *        "paginate": false,
10516.
         *        "retrieve": true
10517.
         *      } );
10518.
         *    }
10519.
         *
10520.
         *    function tableActions ()
10521.
         *    {
10522.
         *      var table = initTable();
10523.
         *      // perform API operations with oTable
10524.
         *    }
10525.
         */
10526.
        "bRetrieve": false,
10527.
    
10528.
    
10529.
        /**
10530.
         * When vertical (y) scrolling is enabled, DataTables will force the height of
10531.
         * the table's viewport to the given height at all times (useful for layout).
10532.
         * However, this can look odd when filtering data down to a small data set,
10533.
         * and the footer is left "floating" further down. This parameter (when
10534.
         * enabled) will cause DataTables to collapse the table's viewport down when
10535.
         * the result set will fit within the given Y height.
10536.
         *  @type boolean
10537.
         *  @default false
10538.
         *
10539.
         *  @dtopt Options
10540.
         *  @name DataTable.defaults.scrollCollapse
10541.
         *
10542.
         *  @example
10543.
         *    $(document).ready( function() {
10544.
         *      $('#example').dataTable( {
10545.
         *        "scrollY": "200",
10546.
         *        "scrollCollapse": true
10547.
         *      } );
10548.
         *    } );
10549.
         */
10550.
        "bScrollCollapse": false,
10551.
    
10552.
    
10553.
        /**
10554.
         * Configure DataTables to use server-side processing. Note that the
10555.
         * `ajax` parameter must also be given in order to give DataTables a
10556.
         * source to obtain the required data for each draw.
10557.
         *  @type boolean
10558.
         *  @default false
10559.
         *
10560.
         *  @dtopt Features
10561.
         *  @dtopt Server-side
10562.
         *  @name DataTable.defaults.serverSide
10563.
         *
10564.
         *  @example
10565.
         *    $(document).ready( function () {
10566.
         *      $('#example').dataTable( {
10567.
         *        "serverSide": true,
10568.
         *        "ajax": "xhr.php"
10569.
         *      } );
10570.
         *    } );
10571.
         */
10572.
        "bServerSide": false,
10573.
    
10574.
    
10575.
        /**
10576.
         * Enable or disable sorting of columns. Sorting of individual columns can be
10577.
         * disabled by the `sortable` option for each column.
10578.
         *  @type boolean
10579.
         *  @default true
10580.
         *
10581.
         *  @dtopt Features
10582.
         *  @name DataTable.defaults.ordering
10583.
         *
10584.
         *  @example
10585.
         *    $(document).ready( function () {
10586.
         *      $('#example').dataTable( {
10587.
         *        "ordering": false
10588.
         *      } );
10589.
         *    } );
10590.
         */
10591.
        "bSort": true,
10592.
    
10593.
    
10594.
        /**
10595.
         * Enable or display DataTables' ability to sort multiple columns at the
10596.
         * same time (activated by shift-click by the user).
10597.
         *  @type boolean
10598.
         *  @default true
10599.
         *
10600.
         *  @dtopt Options
10601.
         *  @name DataTable.defaults.orderMulti
10602.
         *
10603.
         *  @example
10604.
         *    // Disable multiple column sorting ability
10605.
         *    $(document).ready( function () {
10606.
         *      $('#example').dataTable( {
10607.
         *        "orderMulti": false
10608.
         *      } );
10609.
         *    } );
10610.
         */
10611.
        "bSortMulti": true,
10612.
    
10613.
    
10614.
        /**
10615.
         * Allows control over whether DataTables should use the top (true) unique
10616.
         * cell that is found for a single column, or the bottom (false - default).
10617.
         * This is useful when using complex headers.
10618.
         *  @type boolean
10619.
         *  @default false
10620.
         *
10621.
         *  @dtopt Options
10622.
         *  @name DataTable.defaults.orderCellsTop
10623.
         *
10624.
         *  @example
10625.
         *    $(document).ready( function() {
10626.
         *      $('#example').dataTable( {
10627.
         *        "orderCellsTop": true
10628.
         *      } );
10629.
         *    } );
10630.
         */
10631.
        "bSortCellsTop": false,
10632.
    
10633.
    
10634.
        /**
10635.
         * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10636.
         * `sorting\_3` to the columns which are currently being sorted on. This is
10637.
         * presented as a feature switch as it can increase processing time (while
10638.
         * classes are removed and added) so for large data sets you might want to
10639.
         * turn this off.
10640.
         *  @type boolean
10641.
         *  @default true
10642.
         *
10643.
         *  @dtopt Features
10644.
         *  @name DataTable.defaults.orderClasses
10645.
         *
10646.
         *  @example
10647.
         *    $(document).ready( function () {
10648.
         *      $('#example').dataTable( {
10649.
         *        "orderClasses": false
10650.
         *      } );
10651.
         *    } );
10652.
         */
10653.
        "bSortClasses": true,
10654.
    
10655.
    
10656.
        /**
10657.
         * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10658.
         * used to save table display information such as pagination information,
10659.
         * display length, filtering and sorting. As such when the end user reloads
10660.
         * the page the display display will match what thy had previously set up.
10661.
         *
10662.
         * Due to the use of `localStorage` the default state saving is not supported
10663.
         * in IE6 or 7. If state saving is required in those browsers, use
10664.
         * `stateSaveCallback` to provide a storage solution such as cookies.
10665.
         *  @type boolean
10666.
         *  @default false
10667.
         *
10668.
         *  @dtopt Features
10669.
         *  @name DataTable.defaults.stateSave
10670.
         *
10671.
         *  @example
10672.
         *    $(document).ready( function () {
10673.
         *      $('#example').dataTable( {
10674.
         *        "stateSave": true
10675.
         *      } );
10676.
         *    } );
10677.
         */
10678.
        "bStateSave": false,
10679.
    
10680.
    
10681.
        /**
10682.
         * This function is called when a TR element is created (and all TD child
10683.
         * elements have been inserted), or registered if using a DOM source, allowing
10684.
         * manipulation of the TR element (adding classes etc).
10685.
         *  @type function
10686.
         *  @param {node} row "TR" element for the current row
10687.
         *  @param {array} data Raw data array for this row
10688.
         *  @param {int} dataIndex The index of this row in the internal aoData array
10689.
         *
10690.
         *  @dtopt Callbacks
10691.
         *  @name DataTable.defaults.createdRow
10692.
         *
10693.
         *  @example
10694.
         *    $(document).ready( function() {
10695.
         *      $('#example').dataTable( {
10696.
         *        "createdRow": function( row, data, dataIndex ) {
10697.
         *          // Bold the grade for all 'A' grade browsers
10698.
         *          if ( data[4] == "A" )
10699.
         *          {
10700.
         *            $('td:eq(4)', row).html( '<b>A</b>' );
10701.
         *          }
10702.
         *        }
10703.
         *      } );
10704.
         *    } );
10705.
         */
10706.
        "fnCreatedRow": null,
10707.
    
10708.
    
10709.
        /**
10710.
         * This function is called on every 'draw' event, and allows you to
10711.
         * dynamically modify any aspect you want about the created DOM.
10712.
         *  @type function
10713.
         *  @param {object} settings DataTables settings object
10714.
         *
10715.
         *  @dtopt Callbacks
10716.
         *  @name DataTable.defaults.drawCallback
10717.
         *
10718.
         *  @example
10719.
         *    $(document).ready( function() {
10720.
         *      $('#example').dataTable( {
10721.
         *        "drawCallback": function( settings ) {
10722.
         *          alert( 'DataTables has redrawn the table' );
10723.
         *        }
10724.
         *      } );
10725.
         *    } );
10726.
         */
10727.
        "fnDrawCallback": null,
10728.
    
10729.
    
10730.
        /**
10731.
         * Identical to fnHeaderCallback() but for the table footer this function
10732.
         * allows you to modify the table footer on every 'draw' event.
10733.
         *  @type function
10734.
         *  @param {node} foot "TR" element for the footer
10735.
         *  @param {array} data Full table data (as derived from the original HTML)
10736.
         *  @param {int} start Index for the current display starting point in the
10737.
         *    display array
10738.
         *  @param {int} end Index for the current display ending point in the
10739.
         *    display array
10740.
         *  @param {array int} display Index array to translate the visual position
10741.
         *    to the full data array
10742.
         *
10743.
         *  @dtopt Callbacks
10744.
         *  @name DataTable.defaults.footerCallback
10745.
         *
10746.
         *  @example
10747.
         *    $(document).ready( function() {
10748.
         *      $('#example').dataTable( {
10749.
         *        "footerCallback": function( tfoot, data, start, end, display ) {
10750.
         *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10751.
         *        }
10752.
         *      } );
10753.
         *    } )
10754.
         */
10755.
        "fnFooterCallback": null,
10756.
    
10757.
    
10758.
        /**
10759.
         * When rendering large numbers in the information element for the table
10760.
         * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10761.
         * to have a comma separator for the 'thousands' units (e.g. 1 million is
10762.
         * rendered as "1,000,000") to help readability for the end user. This
10763.
         * function will override the default method DataTables uses.
10764.
         *  @type function
10765.
         *  @member
10766.
         *  @param {int} toFormat number to be formatted
10767.
         *  @returns {string} formatted string for DataTables to show the number
10768.
         *
10769.
         *  @dtopt Callbacks
10770.
         *  @name DataTable.defaults.formatNumber
10771.
         *
10772.
         *  @example
10773.
         *    // Format a number using a single quote for the separator (note that
10774.
         *    // this can also be done with the language.thousands option)
10775.
         *    $(document).ready( function() {
10776.
         *      $('#example').dataTable( {
10777.
         *        "formatNumber": function ( toFormat ) {
10778.
         *          return toFormat.toString().replace(
10779.
         *            /\B(?=(\d{3})+(?!\d))/g, "'"
10780.
         *          );
10781.
         *        };
10782.
         *      } );
10783.
         *    } );
10784.
         */
10785.
        "fnFormatNumber": function ( toFormat ) {
10786.
            return toFormat.toString().replace(
10787.
                /\B(?=(\d{3})+(?!\d))/g,
10788.
                this.oLanguage.sThousands
10789.
            );
10790.
        },
10791.
    
10792.
    
10793.
        /**
10794.
         * This function is called on every 'draw' event, and allows you to
10795.
         * dynamically modify the header row. This can be used to calculate and
10796.
         * display useful information about the table.
10797.
         *  @type function
10798.
         *  @param {node} head "TR" element for the header
10799.
         *  @param {array} data Full table data (as derived from the original HTML)
10800.
         *  @param {int} start Index for the current display starting point in the
10801.
         *    display array
10802.
         *  @param {int} end Index for the current display ending point in the
10803.
         *    display array
10804.
         *  @param {array int} display Index array to translate the visual position
10805.
         *    to the full data array
10806.
         *
10807.
         *  @dtopt Callbacks
10808.
         *  @name DataTable.defaults.headerCallback
10809.
         *
10810.
         *  @example
10811.
         *    $(document).ready( function() {
10812.
         *      $('#example').dataTable( {
10813.
         *        "fheaderCallback": function( head, data, start, end, display ) {
10814.
         *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10815.
         *        }
10816.
         *      } );
10817.
         *    } )
10818.
         */
10819.
        "fnHeaderCallback": null,
10820.
    
10821.
    
10822.
        /**
10823.
         * The information element can be used to convey information about the current
10824.
         * state of the table. Although the internationalisation options presented by
10825.
         * DataTables are quite capable of dealing with most customisations, there may
10826.
         * be times where you wish to customise the string further. This callback
10827.
         * allows you to do exactly that.
10828.
         *  @type function
10829.
         *  @param {object} oSettings DataTables settings object
10830.
         *  @param {int} start Starting position in data for the draw
10831.
         *  @param {int} end End position in data for the draw
10832.
         *  @param {int} max Total number of rows in the table (regardless of
10833.
         *    filtering)
10834.
         *  @param {int} total Total number of rows in the data set, after filtering
10835.
         *  @param {string} pre The string that DataTables has formatted using it's
10836.
         *    own rules
10837.
         *  @returns {string} The string to be displayed in the information element.
10838.
         *
10839.
         *  @dtopt Callbacks
10840.
         *  @name DataTable.defaults.infoCallback
10841.
         *
10842.
         *  @example
10843.
         *    $('#example').dataTable( {
10844.
         *      "infoCallback": function( settings, start, end, max, total, pre ) {
10845.
         *        return start +" to "+ end;
10846.
         *      }
10847.
         *    } );
10848.
         */
10849.
        "fnInfoCallback": null,
10850.
    
10851.
    
10852.
        /**
10853.
         * Called when the table has been initialised. Normally DataTables will
10854.
         * initialise sequentially and there will be no need for this function,
10855.
         * however, this does not hold true when using external language information
10856.
         * since that is obtained using an async XHR call.
10857.
         *  @type function
10858.
         *  @param {object} settings DataTables settings object
10859.
         *  @param {object} json The JSON object request from the server - only
10860.
         *    present if client-side Ajax sourced data is used
10861.
         *
10862.
         *  @dtopt Callbacks
10863.
         *  @name DataTable.defaults.initComplete
10864.
         *
10865.
         *  @example
10866.
         *    $(document).ready( function() {
10867.
         *      $('#example').dataTable( {
10868.
         *        "initComplete": function(settings, json) {
10869.
         *          alert( 'DataTables has finished its initialisation.' );
10870.
         *        }
10871.
         *      } );
10872.
         *    } )
10873.
         */
10874.
        "fnInitComplete": null,
10875.
    
10876.
    
10877.
        /**
10878.
         * Called at the very start of each table draw and can be used to cancel the
10879.
         * draw by returning false, any other return (including undefined) results in
10880.
         * the full draw occurring).
10881.
         *  @type function
10882.
         *  @param {object} settings DataTables settings object
10883.
         *  @returns {boolean} False will cancel the draw, anything else (including no
10884.
         *    return) will allow it to complete.
10885.
         *
10886.
         *  @dtopt Callbacks
10887.
         *  @name DataTable.defaults.preDrawCallback
10888.
         *
10889.
         *  @example
10890.
         *    $(document).ready( function() {
10891.
         *      $('#example').dataTable( {
10892.
         *        "preDrawCallback": function( settings ) {
10893.
         *          if ( $('#test').val() == 1 ) {
10894.
         *            return false;
10895.
         *          }
10896.
         *        }
10897.
         *      } );
10898.
         *    } );
10899.
         */
10900.
        "fnPreDrawCallback": null,
10901.
    
10902.
    
10903.
        /**
10904.
         * This function allows you to 'post process' each row after it have been
10905.
         * generated for each table draw, but before it is rendered on screen. This
10906.
         * function might be used for setting the row class name etc.
10907.
         *  @type function
10908.
         *  @param {node} row "TR" element for the current row
10909.
         *  @param {array} data Raw data array for this row
10910.
         *  @param {int} displayIndex The display index for the current table draw
10911.
         *  @param {int} displayIndexFull The index of the data in the full list of
10912.
         *    rows (after filtering)
10913.
         *
10914.
         *  @dtopt Callbacks
10915.
         *  @name DataTable.defaults.rowCallback
10916.
         *
10917.
         *  @example
10918.
         *    $(document).ready( function() {
10919.
         *      $('#example').dataTable( {
10920.
         *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10921.
         *          // Bold the grade for all 'A' grade browsers
10922.
         *          if ( data[4] == "A" ) {
10923.
         *            $('td:eq(4)', row).html( '<b>A</b>' );
10924.
         *          }
10925.
         *        }
10926.
         *      } );
10927.
         *    } );
10928.
         */
10929.
        "fnRowCallback": null,
10930.
    
10931.
    
10932.
        /**
10933.
         * __Deprecated__ The functionality provided by this parameter has now been
10934.
         * superseded by that provided through `ajax`, which should be used instead.
10935.
         *
10936.
         * This parameter allows you to override the default function which obtains
10937.
         * the data from the server so something more suitable for your application.
10938.
         * For example you could use POST data, or pull information from a Gears or
10939.
         * AIR database.
10940.
         *  @type function
10941.
         *  @member
10942.
         *  @param {string} source HTTP source to obtain the data from (`ajax`)
10943.
         *  @param {array} data A key/value pair object containing the data to send
10944.
         *    to the server
10945.
         *  @param {function} callback to be called on completion of the data get
10946.
         *    process that will draw the data on the page.
10947.
         *  @param {object} settings DataTables settings object
10948.
         *
10949.
         *  @dtopt Callbacks
10950.
         *  @dtopt Server-side
10951.
         *  @name DataTable.defaults.serverData
10952.
         *
10953.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
10954.
         */
10955.
        "fnServerData": null,
10956.
    
10957.
    
10958.
        /**
10959.
         * __Deprecated__ The functionality provided by this parameter has now been
10960.
         * superseded by that provided through `ajax`, which should be used instead.
10961.
         *
10962.
         *  It is often useful to send extra data to the server when making an Ajax
10963.
         * request - for example custom filtering information, and this callback
10964.
         * function makes it trivial to send extra information to the server. The
10965.
         * passed in parameter is the data set that has been constructed by
10966.
         * DataTables, and you can add to this or modify it as you require.
10967.
         *  @type function
10968.
         *  @param {array} data Data array (array of objects which are name/value
10969.
         *    pairs) that has been constructed by DataTables and will be sent to the
10970.
         *    server. In the case of Ajax sourced data with server-side processing
10971.
         *    this will be an empty array, for server-side processing there will be a
10972.
         *    significant number of parameters!
10973.
         *  @returns {undefined} Ensure that you modify the data array passed in,
10974.
         *    as this is passed by reference.
10975.
         *
10976.
         *  @dtopt Callbacks
10977.
         *  @dtopt Server-side
10978.
         *  @name DataTable.defaults.serverParams
10979.
         *
10980.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
10981.
         */
10982.
        "fnServerParams": null,
10983.
    
10984.
    
10985.
        /**
10986.
         * Load the table state. With this function you can define from where, and how, the
10987.
         * state of a table is loaded. By default DataTables will load from `localStorage`
10988.
         * but you might wish to use a server-side database or cookies.
10989.
         *  @type function
10990.
         *  @member
10991.
         *  @param {object} settings DataTables settings object
10992.
         *  @param {object} callback Callback that can be executed when done. It
10993.
         *    should be passed the loaded state object.
10994.
         *  @return {object} The DataTables state object to be loaded
10995.
         *
10996.
         *  @dtopt Callbacks
10997.
         *  @name DataTable.defaults.stateLoadCallback
10998.
         *
10999.
         *  @example
11000.
         *    $(document).ready( function() {
11001.
         *      $('#example').dataTable( {
11002.
         *        "stateSave": true,
11003.
         *        "stateLoadCallback": function (settings, callback) {
11004.
         *          $.ajax( {
11005.
         *            "url": "/state_load",
11006.
         *            "dataType": "json",
11007.
         *            "success": function (json) {
11008.
         *              callback( json );
11009.
         *            }
11010.
         *          } );
11011.
         *        }
11012.
         *      } );
11013.
         *    } );
11014.
         */
11015.
        "fnStateLoadCallback": function ( settings ) {
11016.
            try {
11017.
                return JSON.parse(
11018.
                    (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
11019.
                        'DataTables_'+settings.sInstance+'_'+location.pathname
11020.
                    )
11021.
                );
11022.
            } catch (e) {
11023.
                return {};
11024.
            }
11025.
        },
11026.
    
11027.
    
11028.
        /**
11029.
         * Callback which allows modification of the saved state prior to loading that state.
11030.
         * This callback is called when the table is loading state from the stored data, but
11031.
         * prior to the settings object being modified by the saved state. Note that for
11032.
         * plug-in authors, you should use the `stateLoadParams` event to load parameters for
11033.
         * a plug-in.
11034.
         *  @type function
11035.
         *  @param {object} settings DataTables settings object
11036.
         *  @param {object} data The state object that is to be loaded
11037.
         *
11038.
         *  @dtopt Callbacks
11039.
         *  @name DataTable.defaults.stateLoadParams
11040.
         *
11041.
         *  @example
11042.
         *    // Remove a saved filter, so filtering is never loaded
11043.
         *    $(document).ready( function() {
11044.
         *      $('#example').dataTable( {
11045.
         *        "stateSave": true,
11046.
         *        "stateLoadParams": function (settings, data) {
11047.
         *          data.oSearch.sSearch = "";
11048.
         *        }
11049.
         *      } );
11050.
         *    } );
11051.
         *
11052.
         *  @example
11053.
         *    // Disallow state loading by returning false
11054.
         *    $(document).ready( function() {
11055.
         *      $('#example').dataTable( {
11056.
         *        "stateSave": true,
11057.
         *        "stateLoadParams": function (settings, data) {
11058.
         *          return false;
11059.
         *        }
11060.
         *      } );
11061.
         *    } );
11062.
         */
11063.
        "fnStateLoadParams": null,
11064.
    
11065.
    
11066.
        /**
11067.
         * Callback that is called when the state has been loaded from the state saving method
11068.
         * and the DataTables settings object has been modified as a result of the loaded state.
11069.
         *  @type function
11070.
         *  @param {object} settings DataTables settings object
11071.
         *  @param {object} data The state object that was loaded
11072.
         *
11073.
         *  @dtopt Callbacks
11074.
         *  @name DataTable.defaults.stateLoaded
11075.
         *
11076.
         *  @example
11077.
         *    // Show an alert with the filtering value that was saved
11078.
         *    $(document).ready( function() {
11079.
         *      $('#example').dataTable( {
11080.
         *        "stateSave": true,
11081.
         *        "stateLoaded": function (settings, data) {
11082.
         *          alert( 'Saved filter was: '+data.oSearch.sSearch );
11083.
         *        }
11084.
         *      } );
11085.
         *    } );
11086.
         */
11087.
        "fnStateLoaded": null,
11088.
    
11089.
    
11090.
        /**
11091.
         * Save the table state. This function allows you to define where and how the state
11092.
         * information for the table is stored By default DataTables will use `localStorage`
11093.
         * but you might wish to use a server-side database or cookies.
11094.
         *  @type function
11095.
         *  @member
11096.
         *  @param {object} settings DataTables settings object
11097.
         *  @param {object} data The state object to be saved
11098.
         *
11099.
         *  @dtopt Callbacks
11100.
         *  @name DataTable.defaults.stateSaveCallback
11101.
         *
11102.
         *  @example
11103.
         *    $(document).ready( function() {
11104.
         *      $('#example').dataTable( {
11105.
         *        "stateSave": true,
11106.
         *        "stateSaveCallback": function (settings, data) {
11107.
         *          // Send an Ajax request to the server with the state object
11108.
         *          $.ajax( {
11109.
         *            "url": "/state_save",
11110.
         *            "data": data,
11111.
         *            "dataType": "json",
11112.
         *            "method": "POST"
11113.
         *            "success": function () {}
11114.
         *          } );
11115.
         *        }
11116.
         *      } );
11117.
         *    } );
11118.
         */
11119.
        "fnStateSaveCallback": function ( settings, data ) {
11120.
            try {
11121.
                (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
11122.
                    'DataTables_'+settings.sInstance+'_'+location.pathname,
11123.
                    JSON.stringify( data )
11124.
                );
11125.
            } catch (e) {}
11126.
        },
11127.
    
11128.
    
11129.
        /**
11130.
         * Callback which allows modification of the state to be saved. Called when the table
11131.
         * has changed state a new state save is required. This method allows modification of
11132.
         * the state saving object prior to actually doing the save, including addition or
11133.
         * other state properties or modification. Note that for plug-in authors, you should
11134.
         * use the `stateSaveParams` event to save parameters for a plug-in.
11135.
         *  @type function
11136.
         *  @param {object} settings DataTables settings object
11137.
         *  @param {object} data The state object to be saved
11138.
         *
11139.
         *  @dtopt Callbacks
11140.
         *  @name DataTable.defaults.stateSaveParams
11141.
         *
11142.
         *  @example
11143.
         *    // Remove a saved filter, so filtering is never saved
11144.
         *    $(document).ready( function() {
11145.
         *      $('#example').dataTable( {
11146.
         *        "stateSave": true,
11147.
         *        "stateSaveParams": function (settings, data) {
11148.
         *          data.oSearch.sSearch = "";
11149.
         *        }
11150.
         *      } );
11151.
         *    } );
11152.
         */
11153.
        "fnStateSaveParams": null,
11154.
    
11155.
    
11156.
        /**
11157.
         * Duration for which the saved state information is considered valid. After this period
11158.
         * has elapsed the state will be returned to the default.
11159.
         * Value is given in seconds.
11160.
         *  @type int
11161.
         *  @default 7200 <i>(2 hours)</i>
11162.
         *
11163.
         *  @dtopt Options
11164.
         *  @name DataTable.defaults.stateDuration
11165.
         *
11166.
         *  @example
11167.
         *    $(document).ready( function() {
11168.
         *      $('#example').dataTable( {
11169.
         *        "stateDuration": 60*60*24; // 1 day
11170.
         *      } );
11171.
         *    } )
11172.
         */
11173.
        "iStateDuration": 7200,
11174.
    
11175.
    
11176.
        /**
11177.
         * When enabled DataTables will not make a request to the server for the first
11178.
         * page draw - rather it will use the data already on the page (no sorting etc
11179.
         * will be applied to it), thus saving on an XHR at load time. `deferLoading`
11180.
         * is used to indicate that deferred loading is required, but it is also used
11181.
         * to tell DataTables how many records there are in the full table (allowing
11182.
         * the information element and pagination to be displayed correctly). In the case
11183.
         * where a filtering is applied to the table on initial load, this can be
11184.
         * indicated by giving the parameter as an array, where the first element is
11185.
         * the number of records available after filtering and the second element is the
11186.
         * number of records without filtering (allowing the table information element
11187.
         * to be shown correctly).
11188.
         *  @type int | array
11189.
         *  @default null
11190.
         *
11191.
         *  @dtopt Options
11192.
         *  @name DataTable.defaults.deferLoading
11193.
         *
11194.
         *  @example
11195.
         *    // 57 records available in the table, no filtering applied
11196.
         *    $(document).ready( function() {
11197.
         *      $('#example').dataTable( {
11198.
         *        "serverSide": true,
11199.
         *        "ajax": "scripts/server_processing.php",
11200.
         *        "deferLoading": 57
11201.
         *      } );
11202.
         *    } );
11203.
         *
11204.
         *  @example
11205.
         *    // 57 records after filtering, 100 without filtering (an initial filter applied)
11206.
         *    $(document).ready( function() {
11207.
         *      $('#example').dataTable( {
11208.
         *        "serverSide": true,
11209.
         *        "ajax": "scripts/server_processing.php",
11210.
         *        "deferLoading": [ 57, 100 ],
11211.
         *        "search": {
11212.
         *          "search": "my_filter"
11213.
         *        }
11214.
         *      } );
11215.
         *    } );
11216.
         */
11217.
        "iDeferLoading": null,
11218.
    
11219.
    
11220.
        /**
11221.
         * Number of rows to display on a single page when using pagination. If
11222.
         * feature enabled (`lengthChange`) then the end user will be able to override
11223.
         * this to a custom setting using a pop-up menu.
11224.
         *  @type int
11225.
         *  @default 10
11226.
         *
11227.
         *  @dtopt Options
11228.
         *  @name DataTable.defaults.pageLength
11229.
         *
11230.
         *  @example
11231.
         *    $(document).ready( function() {
11232.
         *      $('#example').dataTable( {
11233.
         *        "pageLength": 50
11234.
         *      } );
11235.
         *    } )
11236.
         */
11237.
        "iDisplayLength": 10,
11238.
    
11239.
    
11240.
        /**
11241.
         * Define the starting point for data display when using DataTables with
11242.
         * pagination. Note that this parameter is the number of records, rather than
11243.
         * the page number, so if you have 10 records per page and want to start on
11244.
         * the third page, it should be "20".
11245.
         *  @type int
11246.
         *  @default 0
11247.
         *
11248.
         *  @dtopt Options
11249.
         *  @name DataTable.defaults.displayStart
11250.
         *
11251.
         *  @example
11252.
         *    $(document).ready( function() {
11253.
         *      $('#example').dataTable( {
11254.
         *        "displayStart": 20
11255.
         *      } );
11256.
         *    } )
11257.
         */
11258.
        "iDisplayStart": 0,
11259.
    
11260.
    
11261.
        /**
11262.
         * By default DataTables allows keyboard navigation of the table (sorting, paging,
11263.
         * and filtering) by adding a `tabindex` attribute to the required elements. This
11264.
         * allows you to tab through the controls and press the enter key to activate them.
11265.
         * The tabindex is default 0, meaning that the tab follows the flow of the document.
11266.
         * You can overrule this using this parameter if you wish. Use a value of -1 to
11267.
         * disable built-in keyboard navigation.
11268.
         *  @type int
11269.
         *  @default 0
11270.
         *
11271.
         *  @dtopt Options
11272.
         *  @name DataTable.defaults.tabIndex
11273.
         *
11274.
         *  @example
11275.
         *    $(document).ready( function() {
11276.
         *      $('#example').dataTable( {
11277.
         *        "tabIndex": 1
11278.
         *      } );
11279.
         *    } );
11280.
         */
11281.
        "iTabIndex": 0,
11282.
    
11283.
    
11284.
        /**
11285.
         * Classes that DataTables assigns to the various components and features
11286.
         * that it adds to the HTML table. This allows classes to be configured
11287.
         * during initialisation in addition to through the static
11288.
         * {@link DataTable.ext.oStdClasses} object).
11289.
         *  @namespace
11290.
         *  @name DataTable.defaults.classes
11291.
         */
11292.
        "oClasses": {},
11293.
    
11294.
    
11295.
        /**
11296.
         * All strings that DataTables uses in the user interface that it creates
11297.
         * are defined in this object, allowing you to modified them individually or
11298.
         * completely replace them all as required.
11299.
         *  @namespace
11300.
         *  @name DataTable.defaults.language
11301.
         */
11302.
        "oLanguage": {
11303.
            /**
11304.
             * Strings that are used for WAI-ARIA labels and controls only (these are not
11305.
             * actually visible on the page, but will be read by screenreaders, and thus
11306.
             * must be internationalised as well).
11307.
             *  @namespace
11308.
             *  @name DataTable.defaults.language.aria
11309.
             */
11310.
            "oAria": {
11311.
                /**
11312.
                 * ARIA label that is added to the table headers when the column may be
11313.
                 * sorted ascending by activing the column (click or return when focused).
11314.
                 * Note that the column header is prefixed to this string.
11315.
                 *  @type string
11316.
                 *  @default : activate to sort column ascending
11317.
                 *
11318.
                 *  @dtopt Language
11319.
                 *  @name DataTable.defaults.language.aria.sortAscending
11320.
                 *
11321.
                 *  @example
11322.
                 *    $(document).ready( function() {
11323.
                 *      $('#example').dataTable( {
11324.
                 *        "language": {
11325.
                 *          "aria": {
11326.
                 *            "sortAscending": " - click/return to sort ascending"
11327.
                 *          }
11328.
                 *        }
11329.
                 *      } );
11330.
                 *    } );
11331.
                 */
11332.
                "sSortAscending": ": activate to sort column ascending",
11333.
    
11334.
                /**
11335.
                 * ARIA label that is added to the table headers when the column may be
11336.
                 * sorted descending by activing the column (click or return when focused).
11337.
                 * Note that the column header is prefixed to this string.
11338.
                 *  @type string
11339.
                 *  @default : activate to sort column ascending
11340.
                 *
11341.
                 *  @dtopt Language
11342.
                 *  @name DataTable.defaults.language.aria.sortDescending
11343.
                 *
11344.
                 *  @example
11345.
                 *    $(document).ready( function() {
11346.
                 *      $('#example').dataTable( {
11347.
                 *        "language": {
11348.
                 *          "aria": {
11349.
                 *            "sortDescending": " - click/return to sort descending"
11350.
                 *          }
11351.
                 *        }
11352.
                 *      } );
11353.
                 *    } );
11354.
                 */
11355.
                "sSortDescending": ": activate to sort column descending"
11356.
            },
11357.
    
11358.
            /**
11359.
             * Pagination string used by DataTables for the built-in pagination
11360.
             * control types.
11361.
             *  @namespace
11362.
             *  @name DataTable.defaults.language.paginate
11363.
             */
11364.
            "oPaginate": {
11365.
                /**
11366.
                 * Text to use when using the 'full_numbers' type of pagination for the
11367.
                 * button to take the user to the first page.
11368.
                 *  @type string
11369.
                 *  @default First
11370.
                 *
11371.
                 *  @dtopt Language
11372.
                 *  @name DataTable.defaults.language.paginate.first
11373.
                 *
11374.
                 *  @example
11375.
                 *    $(document).ready( function() {
11376.
                 *      $('#example').dataTable( {
11377.
                 *        "language": {
11378.
                 *          "paginate": {
11379.
                 *            "first": "First page"
11380.
                 *          }
11381.
                 *        }
11382.
                 *      } );
11383.
                 *    } );
11384.
                 */
11385.
                "sFirst": "First",
11386.
    
11387.
    
11388.
                /**
11389.
                 * Text to use when using the 'full_numbers' type of pagination for the
11390.
                 * button to take the user to the last page.
11391.
                 *  @type string
11392.
                 *  @default Last
11393.
                 *
11394.
                 *  @dtopt Language
11395.
                 *  @name DataTable.defaults.language.paginate.last
11396.
                 *
11397.
                 *  @example
11398.
                 *    $(document).ready( function() {
11399.
                 *      $('#example').dataTable( {
11400.
                 *        "language": {
11401.
                 *          "paginate": {
11402.
                 *            "last": "Last page"
11403.
                 *          }
11404.
                 *        }
11405.
                 *      } );
11406.
                 *    } );
11407.
                 */
11408.
                "sLast": "Last",
11409.
    
11410.
    
11411.
                /**
11412.
                 * Text to use for the 'next' pagination button (to take the user to the
11413.
                 * next page).
11414.
                 *  @type string
11415.
                 *  @default Next
11416.
                 *
11417.
                 *  @dtopt Language
11418.
                 *  @name DataTable.defaults.language.paginate.next
11419.
                 *
11420.
                 *  @example
11421.
                 *    $(document).ready( function() {
11422.
                 *      $('#example').dataTable( {
11423.
                 *        "language": {
11424.
                 *          "paginate": {
11425.
                 *            "next": "Next page"
11426.
                 *          }
11427.
                 *        }
11428.
                 *      } );
11429.
                 *    } );
11430.
                 */
11431.
                "sNext": "Next",
11432.
    
11433.
    
11434.
                /**
11435.
                 * Text to use for the 'previous' pagination button (to take the user to
11436.
                 * the previous page).
11437.
                 *  @type string
11438.
                 *  @default Previous
11439.
                 *
11440.
                 *  @dtopt Language
11441.
                 *  @name DataTable.defaults.language.paginate.previous
11442.
                 *
11443.
                 *  @example
11444.
                 *    $(document).ready( function() {
11445.
                 *      $('#example').dataTable( {
11446.
                 *        "language": {
11447.
                 *          "paginate": {
11448.
                 *            "previous": "Previous page"
11449.
                 *          }
11450.
                 *        }
11451.
                 *      } );
11452.
                 *    } );
11453.
                 */
11454.
                "sPrevious": "Previous"
11455.
            },
11456.
    
11457.
            /**
11458.
             * This string is shown in preference to `zeroRecords` when the table is
11459.
             * empty of data (regardless of filtering). Note that this is an optional
11460.
             * parameter - if it is not given, the value of `zeroRecords` will be used
11461.
             * instead (either the default or given value).
11462.
             *  @type string
11463.
             *  @default No data available in table
11464.
             *
11465.
             *  @dtopt Language
11466.
             *  @name DataTable.defaults.language.emptyTable
11467.
             *
11468.
             *  @example
11469.
             *    $(document).ready( function() {
11470.
             *      $('#example').dataTable( {
11471.
             *        "language": {
11472.
             *          "emptyTable": "No data available in table"
11473.
             *        }
11474.
             *      } );
11475.
             *    } );
11476.
             */
11477.
            "sEmptyTable": "No data available in table",
11478.
    
11479.
    
11480.
            /**
11481.
             * This string gives information to the end user about the information
11482.
             * that is current on display on the page. The following tokens can be
11483.
             * used in the string and will be dynamically replaced as the table
11484.
             * display updates. This tokens can be placed anywhere in the string, or
11485.
             * removed as needed by the language requires:
11486.
             *
11487.
             * * `\_START\_` - Display index of the first record on the current page
11488.
             * * `\_END\_` - Display index of the last record on the current page
11489.
             * * `\_TOTAL\_` - Number of records in the table after filtering
11490.
             * * `\_MAX\_` - Number of records in the table without filtering
11491.
             * * `\_PAGE\_` - Current page number
11492.
             * * `\_PAGES\_` - Total number of pages of data in the table
11493.
             *
11494.
             *  @type string
11495.
             *  @default Showing _START_ to _END_ of _TOTAL_ entries
11496.
             *
11497.
             *  @dtopt Language
11498.
             *  @name DataTable.defaults.language.info
11499.
             *
11500.
             *  @example
11501.
             *    $(document).ready( function() {
11502.
             *      $('#example').dataTable( {
11503.
             *        "language": {
11504.
             *          "info": "Showing page _PAGE_ of _PAGES_"
11505.
             *        }
11506.
             *      } );
11507.
             *    } );
11508.
             */
11509.
            "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11510.
    
11511.
    
11512.
            /**
11513.
             * Display information string for when the table is empty. Typically the
11514.
             * format of this string should match `info`.
11515.
             *  @type string
11516.
             *  @default Showing 0 to 0 of 0 entries
11517.
             *
11518.
             *  @dtopt Language
11519.
             *  @name DataTable.defaults.language.infoEmpty
11520.
             *
11521.
             *  @example
11522.
             *    $(document).ready( function() {
11523.
             *      $('#example').dataTable( {
11524.
             *        "language": {
11525.
             *          "infoEmpty": "No entries to show"
11526.
             *        }
11527.
             *      } );
11528.
             *    } );
11529.
             */
11530.
            "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11531.
    
11532.
    
11533.
            /**
11534.
             * When a user filters the information in a table, this string is appended
11535.
             * to the information (`info`) to give an idea of how strong the filtering
11536.
             * is. The variable _MAX_ is dynamically updated.
11537.
             *  @type string
11538.
             *  @default (filtered from _MAX_ total entries)
11539.
             *
11540.
             *  @dtopt Language
11541.
             *  @name DataTable.defaults.language.infoFiltered
11542.
             *
11543.
             *  @example
11544.
             *    $(document).ready( function() {
11545.
             *      $('#example').dataTable( {
11546.
             *        "language": {
11547.
             *          "infoFiltered": " - filtering from _MAX_ records"
11548.
             *        }
11549.
             *      } );
11550.
             *    } );
11551.
             */
11552.
            "sInfoFiltered": "(filtered from _MAX_ total entries)",
11553.
    
11554.
    
11555.
            /**
11556.
             * If can be useful to append extra information to the info string at times,
11557.
             * and this variable does exactly that. This information will be appended to
11558.
             * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11559.
             * being used) at all times.
11560.
             *  @type string
11561.
             *  @default <i>Empty string</i>
11562.
             *
11563.
             *  @dtopt Language
11564.
             *  @name DataTable.defaults.language.infoPostFix
11565.
             *
11566.
             *  @example
11567.
             *    $(document).ready( function() {
11568.
             *      $('#example').dataTable( {
11569.
             *        "language": {
11570.
             *          "infoPostFix": "All records shown are derived from real information."
11571.
             *        }
11572.
             *      } );
11573.
             *    } );
11574.
             */
11575.
            "sInfoPostFix": "",
11576.
    
11577.
    
11578.
            /**
11579.
             * This decimal place operator is a little different from the other
11580.
             * language options since DataTables doesn't output floating point
11581.
             * numbers, so it won't ever use this for display of a number. Rather,
11582.
             * what this parameter does is modify the sort methods of the table so
11583.
             * that numbers which are in a format which has a character other than
11584.
             * a period (`.`) as a decimal place will be sorted numerically.
11585.
             *
11586.
             * Note that numbers with different decimal places cannot be shown in
11587.
             * the same table and still be sortable, the table must be consistent.
11588.
             * However, multiple different tables on the page can use different
11589.
             * decimal place characters.
11590.
             *  @type string
11591.
             *  @default 
11592.
             *
11593.
             *  @dtopt Language
11594.
             *  @name DataTable.defaults.language.decimal
11595.
             *
11596.
             *  @example
11597.
             *    $(document).ready( function() {
11598.
             *      $('#example').dataTable( {
11599.
             *        "language": {
11600.
             *          "decimal": ","
11601.
             *          "thousands": "."
11602.
             *        }
11603.
             *      } );
11604.
             *    } );
11605.
             */
11606.
            "sDecimal": "",
11607.
    
11608.
    
11609.
            /**
11610.
             * DataTables has a build in number formatter (`formatNumber`) which is
11611.
             * used to format large numbers that are used in the table information.
11612.
             * By default a comma is used, but this can be trivially changed to any
11613.
             * character you wish with this parameter.
11614.
             *  @type string
11615.
             *  @default ,
11616.
             *
11617.
             *  @dtopt Language
11618.
             *  @name DataTable.defaults.language.thousands
11619.
             *
11620.
             *  @example
11621.
             *    $(document).ready( function() {
11622.
             *      $('#example').dataTable( {
11623.
             *        "language": {
11624.
             *          "thousands": "'"
11625.
             *        }
11626.
             *      } );
11627.
             *    } );
11628.
             */
11629.
            "sThousands": ",",
11630.
    
11631.
    
11632.
            /**
11633.
             * Detail the action that will be taken when the drop down menu for the
11634.
             * pagination length option is changed. The '_MENU_' variable is replaced
11635.
             * with a default select list of 10, 25, 50 and 100, and can be replaced
11636.
             * with a custom select box if required.
11637.
             *  @type string
11638.
             *  @default Show _MENU_ entries
11639.
             *
11640.
             *  @dtopt Language
11641.
             *  @name DataTable.defaults.language.lengthMenu
11642.
             *
11643.
             *  @example
11644.
             *    // Language change only
11645.
             *    $(document).ready( function() {
11646.
             *      $('#example').dataTable( {
11647.
             *        "language": {
11648.
             *          "lengthMenu": "Display _MENU_ records"
11649.
             *        }
11650.
             *      } );
11651.
             *    } );
11652.
             *
11653.
             *  @example
11654.
             *    // Language and options change
11655.
             *    $(document).ready( function() {
11656.
             *      $('#example').dataTable( {
11657.
             *        "language": {
11658.
             *          "lengthMenu": 'Display <select>'+
11659.
             *            '<option value="10">10</option>'+
11660.
             *            '<option value="20">20</option>'+
11661.
             *            '<option value="30">30</option>'+
11662.
             *            '<option value="40">40</option>'+
11663.
             *            '<option value="50">50</option>'+
11664.
             *            '<option value="-1">All</option>'+
11665.
             *            '</select> records'
11666.
             *        }
11667.
             *      } );
11668.
             *    } );
11669.
             */
11670.
            "sLengthMenu": "Show _MENU_ entries",
11671.
    
11672.
    
11673.
            /**
11674.
             * When using Ajax sourced data and during the first draw when DataTables is
11675.
             * gathering the data, this message is shown in an empty row in the table to
11676.
             * indicate to the end user the the data is being loaded. Note that this
11677.
             * parameter is not used when loading data by server-side processing, just
11678.
             * Ajax sourced data with client-side processing.
11679.
             *  @type string
11680.
             *  @default Loading...
11681.
             *
11682.
             *  @dtopt Language
11683.
             *  @name DataTable.defaults.language.loadingRecords
11684.
             *
11685.
             *  @example
11686.
             *    $(document).ready( function() {
11687.
             *      $('#example').dataTable( {
11688.
             *        "language": {
11689.
             *          "loadingRecords": "Please wait - loading..."
11690.
             *        }
11691.
             *      } );
11692.
             *    } );
11693.
             */
11694.
            "sLoadingRecords": "Loading...",
11695.
    
11696.
    
11697.
            /**
11698.
             * Text which is displayed when the table is processing a user action
11699.
             * (usually a sort command or similar).
11700.
             *  @type string
11701.
             *  @default Processing...
11702.
             *
11703.
             *  @dtopt Language
11704.
             *  @name DataTable.defaults.language.processing
11705.
             *
11706.
             *  @example
11707.
             *    $(document).ready( function() {
11708.
             *      $('#example').dataTable( {
11709.
             *        "language": {
11710.
             *          "processing": "DataTables is currently busy"
11711.
             *        }
11712.
             *      } );
11713.
             *    } );
11714.
             */
11715.
            "sProcessing": "Processing...",
11716.
    
11717.
    
11718.
            /**
11719.
             * Details the actions that will be taken when the user types into the
11720.
             * filtering input text box. The variable "_INPUT_", if used in the string,
11721.
             * is replaced with the HTML text box for the filtering input allowing
11722.
             * control over where it appears in the string. If "_INPUT_" is not given
11723.
             * then the input box is appended to the string automatically.
11724.
             *  @type string
11725.
             *  @default Search:
11726.
             *
11727.
             *  @dtopt Language
11728.
             *  @name DataTable.defaults.language.search
11729.
             *
11730.
             *  @example
11731.
             *    // Input text box will be appended at the end automatically
11732.
             *    $(document).ready( function() {
11733.
             *      $('#example').dataTable( {
11734.
             *        "language": {
11735.
             *          "search": "Filter records:"
11736.
             *        }
11737.
             *      } );
11738.
             *    } );
11739.
             *
11740.
             *  @example
11741.
             *    // Specify where the filter should appear
11742.
             *    $(document).ready( function() {
11743.
             *      $('#example').dataTable( {
11744.
             *        "language": {
11745.
             *          "search": "Apply filter _INPUT_ to table"
11746.
             *        }
11747.
             *      } );
11748.
             *    } );
11749.
             */
11750.
            "sSearch": "Search:",
11751.
    
11752.
    
11753.
            /**
11754.
             * Assign a `placeholder` attribute to the search `input` element
11755.
             *  @type string
11756.
             *  @default 
11757.
             *
11758.
             *  @dtopt Language
11759.
             *  @name DataTable.defaults.language.searchPlaceholder
11760.
             */
11761.
            "sSearchPlaceholder": "",
11762.
    
11763.
    
11764.
            /**
11765.
             * All of the language information can be stored in a file on the
11766.
             * server-side, which DataTables will look up if this parameter is passed.
11767.
             * It must store the URL of the language file, which is in a JSON format,
11768.
             * and the object has the same properties as the oLanguage object in the
11769.
             * initialiser object (i.e. the above parameters). Please refer to one of
11770.
             * the example language files to see how this works in action.
11771.
             *  @type string
11772.
             *  @default <i>Empty string - i.e. disabled</i>
11773.
             *
11774.
             *  @dtopt Language
11775.
             *  @name DataTable.defaults.language.url
11776.
             *
11777.
             *  @example
11778.
             *    $(document).ready( function() {
11779.
             *      $('#example').dataTable( {
11780.
             *        "language": {
11781.
             *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11782.
             *        }
11783.
             *      } );
11784.
             *    } );
11785.
             */
11786.
            "sUrl": "",
11787.
    
11788.
    
11789.
            /**
11790.
             * Text shown inside the table records when the is no information to be
11791.
             * displayed after filtering. `emptyTable` is shown when there is simply no
11792.
             * information in the table at all (regardless of filtering).
11793.
             *  @type string
11794.
             *  @default No matching records found
11795.
             *
11796.
             *  @dtopt Language
11797.
             *  @name DataTable.defaults.language.zeroRecords
11798.
             *
11799.
             *  @example
11800.
             *    $(document).ready( function() {
11801.
             *      $('#example').dataTable( {
11802.
             *        "language": {
11803.
             *          "zeroRecords": "No records to display"
11804.
             *        }
11805.
             *      } );
11806.
             *    } );
11807.
             */
11808.
            "sZeroRecords": "No matching records found"
11809.
        },
11810.
    
11811.
    
11812.
        /**
11813.
         * This parameter allows you to have define the global filtering state at
11814.
         * initialisation time. As an object the `search` parameter must be
11815.
         * defined, but all other parameters are optional. When `regex` is true,
11816.
         * the search string will be treated as a regular expression, when false
11817.
         * (default) it will be treated as a straight string. When `smart`
11818.
         * DataTables will use it's smart filtering methods (to word match at
11819.
         * any point in the data), when false this will not be done.
11820.
         *  @namespace
11821.
         *  @extends DataTable.models.oSearch
11822.
         *
11823.
         *  @dtopt Options
11824.
         *  @name DataTable.defaults.search
11825.
         *
11826.
         *  @example
11827.
         *    $(document).ready( function() {
11828.
         *      $('#example').dataTable( {
11829.
         *        "search": {"search": "Initial search"}
11830.
         *      } );
11831.
         *    } )
11832.
         */
11833.
        "oSearch": $.extend( {}, DataTable.models.oSearch ),
11834.
    
11835.
    
11836.
        /**
11837.
         * __Deprecated__ The functionality provided by this parameter has now been
11838.
         * superseded by that provided through `ajax`, which should be used instead.
11839.
         *
11840.
         * By default DataTables will look for the property `data` (or `aaData` for
11841.
         * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11842.
         * source or for server-side processing - this parameter allows that
11843.
         * property to be changed. You can use Javascript dotted object notation to
11844.
         * get a data source for multiple levels of nesting.
11845.
         *  @type string
11846.
         *  @default data
11847.
         *
11848.
         *  @dtopt Options
11849.
         *  @dtopt Server-side
11850.
         *  @name DataTable.defaults.ajaxDataProp
11851.
         *
11852.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
11853.
         */
11854.
        "sAjaxDataProp": "data",
11855.
    
11856.
    
11857.
        /**
11858.
         * __Deprecated__ The functionality provided by this parameter has now been
11859.
         * superseded by that provided through `ajax`, which should be used instead.
11860.
         *
11861.
         * You can instruct DataTables to load data from an external
11862.
         * source using this parameter (use aData if you want to pass data in you
11863.
         * already have). Simply provide a url a JSON object can be obtained from.
11864.
         *  @type string
11865.
         *  @default null
11866.
         *
11867.
         *  @dtopt Options
11868.
         *  @dtopt Server-side
11869.
         *  @name DataTable.defaults.ajaxSource
11870.
         *
11871.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
11872.
         */
11873.
        "sAjaxSource": null,
11874.
    
11875.
    
11876.
        /**
11877.
         * This initialisation variable allows you to specify exactly where in the
11878.
         * DOM you want DataTables to inject the various controls it adds to the page
11879.
         * (for example you might want the pagination controls at the top of the
11880.
         * table). DIV elements (with or without a custom class) can also be added to
11881.
         * aid styling. The follow syntax is used:
11882.
         *   <ul>
11883.
         *     <li>The following options are allowed:
11884.
         *       <ul>
11885.
         *         <li>'l' - Length changing</li>
11886.
         *         <li>'f' - Filtering input</li>
11887.
         *         <li>'t' - The table!</li>
11888.
         *         <li>'i' - Information</li>
11889.
         *         <li>'p' - Pagination</li>
11890.
         *         <li>'r' - pRocessing</li>
11891.
         *       </ul>
11892.
         *     </li>
11893.
         *     <li>The following constants are allowed:
11894.
         *       <ul>
11895.
         *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11896.
         *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11897.
         *       </ul>
11898.
         *     </li>
11899.
         *     <li>The following syntax is expected:
11900.
         *       <ul>
11901.
         *         <li>'&lt;' and '&gt;' - div elements</li>
11902.
         *         <li>'&lt;"class" and '&gt;' - div with a class</li>
11903.
         *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11904.
         *       </ul>
11905.
         *     </li>
11906.
         *     <li>Examples:
11907.
         *       <ul>
11908.
         *         <li>'&lt;"wrapper"flipt&gt;'</li>
11909.
         *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11910.
         *       </ul>
11911.
         *     </li>
11912.
         *   </ul>
11913.
         *  @type string
11914.
         *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11915.
         *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11916.
         *
11917.
         *  @dtopt Options
11918.
         *  @name DataTable.defaults.dom
11919.
         *
11920.
         *  @example
11921.
         *    $(document).ready( function() {
11922.
         *      $('#example').dataTable( {
11923.
         *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11924.
         *      } );
11925.
         *    } );
11926.
         */
11927.
        "sDom": "lfrtip",
11928.
    
11929.
    
11930.
        /**
11931.
         * Search delay option. This will throttle full table searches that use the
11932.
         * DataTables provided search input element (it does not effect calls to
11933.
         * `dt-api search()`, providing a delay before the search is made.
11934.
         *  @type integer
11935.
         *  @default 0
11936.
         *
11937.
         *  @dtopt Options
11938.
         *  @name DataTable.defaults.searchDelay
11939.
         *
11940.
         *  @example
11941.
         *    $(document).ready( function() {
11942.
         *      $('#example').dataTable( {
11943.
         *        "searchDelay": 200
11944.
         *      } );
11945.
         *    } )
11946.
         */
11947.
        "searchDelay": null,
11948.
    
11949.
    
11950.
        /**
11951.
         * DataTables features six different built-in options for the buttons to
11952.
         * display for pagination control:
11953.
         *
11954.
         * * `numbers` - Page number buttons only
11955.
         * * `simple` - 'Previous' and 'Next' buttons only
11956.
         * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11957.
         * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11958.
         * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11959.
         * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11960.
         *  
11961.
         * Further methods can be added using {@link DataTable.ext.oPagination}.
11962.
         *  @type string
11963.
         *  @default simple_numbers
11964.
         *
11965.
         *  @dtopt Options
11966.
         *  @name DataTable.defaults.pagingType
11967.
         *
11968.
         *  @example
11969.
         *    $(document).ready( function() {
11970.
         *      $('#example').dataTable( {
11971.
         *        "pagingType": "full_numbers"
11972.
         *      } );
11973.
         *    } )
11974.
         */
11975.
        "sPaginationType": "simple_numbers",
11976.
    
11977.
    
11978.
        /**
11979.
         * Enable horizontal scrolling. When a table is too wide to fit into a
11980.
         * certain layout, or you have a large number of columns in the table, you
11981.
         * can enable x-scrolling to show the table in a viewport, which can be
11982.
         * scrolled. This property can be `true` which will allow the table to
11983.
         * scroll horizontally when needed, or any CSS unit, or a number (in which
11984.
         * case it will be treated as a pixel measurement). Setting as simply `true`
11985.
         * is recommended.
11986.
         *  @type boolean|string
11987.
         *  @default <i>blank string - i.e. disabled</i>
11988.
         *
11989.
         *  @dtopt Features
11990.
         *  @name DataTable.defaults.scrollX
11991.
         *
11992.
         *  @example
11993.
         *    $(document).ready( function() {
11994.
         *      $('#example').dataTable( {
11995.
         *        "scrollX": true,
11996.
         *        "scrollCollapse": true
11997.
         *      } );
11998.
         *    } );
11999.
         */
12000.
        "sScrollX": "",
12001.
    
12002.
    
12003.
        /**
12004.
         * This property can be used to force a DataTable to use more width than it
12005.
         * might otherwise do when x-scrolling is enabled. For example if you have a
12006.
         * table which requires to be well spaced, this parameter is useful for
12007.
         * "over-sizing" the table, and thus forcing scrolling. This property can by
12008.
         * any CSS unit, or a number (in which case it will be treated as a pixel
12009.
         * measurement).
12010.
         *  @type string
12011.
         *  @default <i>blank string - i.e. disabled</i>
12012.
         *
12013.
         *  @dtopt Options
12014.
         *  @name DataTable.defaults.scrollXInner
12015.
         *
12016.
         *  @example
12017.
         *    $(document).ready( function() {
12018.
         *      $('#example').dataTable( {
12019.
         *        "scrollX": "100%",
12020.
         *        "scrollXInner": "110%"
12021.
         *      } );
12022.
         *    } );
12023.
         */
12024.
        "sScrollXInner": "",
12025.
    
12026.
    
12027.
        /**
12028.
         * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
12029.
         * to the given height, and enable scrolling for any data which overflows the
12030.
         * current viewport. This can be used as an alternative to paging to display
12031.
         * a lot of data in a small area (although paging and scrolling can both be
12032.
         * enabled at the same time). This property can be any CSS unit, or a number
12033.
         * (in which case it will be treated as a pixel measurement).
12034.
         *  @type string
12035.
         *  @default <i>blank string - i.e. disabled</i>
12036.
         *
12037.
         *  @dtopt Features
12038.
         *  @name DataTable.defaults.scrollY
12039.
         *
12040.
         *  @example
12041.
         *    $(document).ready( function() {
12042.
         *      $('#example').dataTable( {
12043.
         *        "scrollY": "200px",
12044.
         *        "paginate": false
12045.
         *      } );
12046.
         *    } );
12047.
         */
12048.
        "sScrollY": "",
12049.
    
12050.
    
12051.
        /**
12052.
         * __Deprecated__ The functionality provided by this parameter has now been
12053.
         * superseded by that provided through `ajax`, which should be used instead.
12054.
         *
12055.
         * Set the HTTP method that is used to make the Ajax call for server-side
12056.
         * processing or Ajax sourced data.
12057.
         *  @type string
12058.
         *  @default GET
12059.
         *
12060.
         *  @dtopt Options
12061.
         *  @dtopt Server-side
12062.
         *  @name DataTable.defaults.serverMethod
12063.
         *
12064.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
12065.
         */
12066.
        "sServerMethod": "GET",
12067.
    
12068.
    
12069.
        /**
12070.
         * DataTables makes use of renderers when displaying HTML elements for
12071.
         * a table. These renderers can be added or modified by plug-ins to
12072.
         * generate suitable mark-up for a site. For example the Bootstrap
12073.
         * integration plug-in for DataTables uses a paging button renderer to
12074.
         * display pagination buttons in the mark-up required by Bootstrap.
12075.
         *
12076.
         * For further information about the renderers available see
12077.
         * DataTable.ext.renderer
12078.
         *  @type string|object
12079.
         *  @default null
12080.
         *
12081.
         *  @name DataTable.defaults.renderer
12082.
         *
12083.
         */
12084.
        "renderer": null,
12085.
    
12086.
    
12087.
        /**
12088.
         * Set the data property name that DataTables should use to get a row's id
12089.
         * to set as the `id` property in the node.
12090.
         *  @type string
12091.
         *  @default DT_RowId
12092.
         *
12093.
         *  @name DataTable.defaults.rowId
12094.
         */
12095.
        "rowId": "DT_RowId"
12096.
    };
12097.
    
12098.
    _fnHungarianMap( DataTable.defaults );
12099.
    
12100.
    
12101.
    
12102.
    /*
12103.
     * Developer note - See note in model.defaults.js about the use of Hungarian
12104.
     * notation and camel case.
12105.
     */
12106.
    
12107.
    /**
12108.
     * Column options that can be given to DataTables at initialisation time.
12109.
     *  @namespace
12110.
     */
12111.
    DataTable.defaults.column = {
12112.
        /**
12113.
         * Define which column(s) an order will occur on for this column. This
12114.
         * allows a column's ordering to take multiple columns into account when
12115.
         * doing a sort or use the data from a different column. For example first
12116.
         * name / last name columns make sense to do a multi-column sort over the
12117.
         * two columns.
12118.
         *  @type array|int
12119.
         *  @default null <i>Takes the value of the column index automatically</i>
12120.
         *
12121.
         *  @name DataTable.defaults.column.orderData
12122.
         *  @dtopt Columns
12123.
         *
12124.
         *  @example
12125.
         *    // Using `columnDefs`
12126.
         *    $(document).ready( function() {
12127.
         *      $('#example').dataTable( {
12128.
         *        "columnDefs": [
12129.
         *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
12130.
         *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
12131.
         *          { "orderData": 2, "targets": [ 2 ] }
12132.
         *        ]
12133.
         *      } );
12134.
         *    } );
12135.
         *
12136.
         *  @example
12137.
         *    // Using `columns`
12138.
         *    $(document).ready( function() {
12139.
         *      $('#example').dataTable( {
12140.
         *        "columns": [
12141.
         *          { "orderData": [ 0, 1 ] },
12142.
         *          { "orderData": [ 1, 0 ] },
12143.
         *          { "orderData": 2 },
12144.
         *          null,
12145.
         *          null
12146.
         *        ]
12147.
         *      } );
12148.
         *    } );
12149.
         */
12150.
        "aDataSort": null,
12151.
        "iDataSort": -1,
12152.
    
12153.
    
12154.
        /**
12155.
         * You can control the default ordering direction, and even alter the
12156.
         * behaviour of the sort handler (i.e. only allow ascending ordering etc)
12157.
         * using this parameter.
12158.
         *  @type array
12159.
         *  @default [ 'asc', 'desc' ]
12160.
         *
12161.
         *  @name DataTable.defaults.column.orderSequence
12162.
         *  @dtopt Columns
12163.
         *
12164.
         *  @example
12165.
         *    // Using `columnDefs`
12166.
         *    $(document).ready( function() {
12167.
         *      $('#example').dataTable( {
12168.
         *        "columnDefs": [
12169.
         *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
12170.
         *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
12171.
         *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
12172.
         *        ]
12173.
         *      } );
12174.
         *    } );
12175.
         *
12176.
         *  @example
12177.
         *    // Using `columns`
12178.
         *    $(document).ready( function() {
12179.
         *      $('#example').dataTable( {
12180.
         *        "columns": [
12181.
         *          null,
12182.
         *          { "orderSequence": [ "asc" ] },
12183.
         *          { "orderSequence": [ "desc", "asc", "asc" ] },
12184.
         *          { "orderSequence": [ "desc" ] },
12185.
         *          null
12186.
         *        ]
12187.
         *      } );
12188.
         *    } );
12189.
         */
12190.
        "asSorting": [ 'asc', 'desc' ],
12191.
    
12192.
    
12193.
        /**
12194.
         * Enable or disable filtering on the data in this column.
12195.
         *  @type boolean
12196.
         *  @default true
12197.
         *
12198.
         *  @name DataTable.defaults.column.searchable
12199.
         *  @dtopt Columns
12200.
         *
12201.
         *  @example
12202.
         *    // Using `columnDefs`
12203.
         *    $(document).ready( function() {
12204.
         *      $('#example').dataTable( {
12205.
         *        "columnDefs": [
12206.
         *          { "searchable": false, "targets": [ 0 ] }
12207.
         *        ] } );
12208.
         *    } );
12209.
         *
12210.
         *  @example
12211.
         *    // Using `columns`
12212.
         *    $(document).ready( function() {
12213.
         *      $('#example').dataTable( {
12214.
         *        "columns": [
12215.
         *          { "searchable": false },
12216.
         *          null,
12217.
         *          null,
12218.
         *          null,
12219.
         *          null
12220.
         *        ] } );
12221.
         *    } );
12222.
         */
12223.
        "bSearchable": true,
12224.
    
12225.
    
12226.
        /**
12227.
         * Enable or disable ordering on this column.
12228.
         *  @type boolean
12229.
         *  @default true
12230.
         *
12231.
         *  @name DataTable.defaults.column.orderable
12232.
         *  @dtopt Columns
12233.
         *
12234.
         *  @example
12235.
         *    // Using `columnDefs`
12236.
         *    $(document).ready( function() {
12237.
         *      $('#example').dataTable( {
12238.
         *        "columnDefs": [
12239.
         *          { "orderable": false, "targets": [ 0 ] }
12240.
         *        ] } );
12241.
         *    } );
12242.
         *
12243.
         *  @example
12244.
         *    // Using `columns`
12245.
         *    $(document).ready( function() {
12246.
         *      $('#example').dataTable( {
12247.
         *        "columns": [
12248.
         *          { "orderable": false },
12249.
         *          null,
12250.
         *          null,
12251.
         *          null,
12252.
         *          null
12253.
         *        ] } );
12254.
         *    } );
12255.
         */
12256.
        "bSortable": true,
12257.
    
12258.
    
12259.
        /**
12260.
         * Enable or disable the display of this column.
12261.
         *  @type boolean
12262.
         *  @default true
12263.
         *
12264.
         *  @name DataTable.defaults.column.visible
12265.
         *  @dtopt Columns
12266.
         *
12267.
         *  @example
12268.
         *    // Using `columnDefs`
12269.
         *    $(document).ready( function() {
12270.
         *      $('#example').dataTable( {
12271.
         *        "columnDefs": [
12272.
         *          { "visible": false, "targets": [ 0 ] }
12273.
         *        ] } );
12274.
         *    } );
12275.
         *
12276.
         *  @example
12277.
         *    // Using `columns`
12278.
         *    $(document).ready( function() {
12279.
         *      $('#example').dataTable( {
12280.
         *        "columns": [
12281.
         *          { "visible": false },
12282.
         *          null,
12283.
         *          null,
12284.
         *          null,
12285.
         *          null
12286.
         *        ] } );
12287.
         *    } );
12288.
         */
12289.
        "bVisible": true,
12290.
    
12291.
    
12292.
        /**
12293.
         * Developer definable function that is called whenever a cell is created (Ajax source,
12294.
         * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12295.
         * allowing you to modify the DOM element (add background colour for example) when the
12296.
         * element is available.
12297.
         *  @type function
12298.
         *  @param {element} td The TD node that has been created
12299.
         *  @param {*} cellData The Data for the cell
12300.
         *  @param {array|object} rowData The data for the whole row
12301.
         *  @param {int} row The row index for the aoData data store
12302.
         *  @param {int} col The column index for aoColumns
12303.
         *
12304.
         *  @name DataTable.defaults.column.createdCell
12305.
         *  @dtopt Columns
12306.
         *
12307.
         *  @example
12308.
         *    $(document).ready( function() {
12309.
         *      $('#example').dataTable( {
12310.
         *        "columnDefs": [ {
12311.
         *          "targets": [3],
12312.
         *          "createdCell": function (td, cellData, rowData, row, col) {
12313.
         *            if ( cellData == "1.7" ) {
12314.
         *              $(td).css('color', 'blue')
12315.
         *            }
12316.
         *          }
12317.
         *        } ]
12318.
         *      });
12319.
         *    } );
12320.
         */
12321.
        "fnCreatedCell": null,
12322.
    
12323.
    
12324.
        /**
12325.
         * This parameter has been replaced by `data` in DataTables to ensure naming
12326.
         * consistency. `dataProp` can still be used, as there is backwards
12327.
         * compatibility in DataTables for this option, but it is strongly
12328.
         * recommended that you use `data` in preference to `dataProp`.
12329.
         *  @name DataTable.defaults.column.dataProp
12330.
         */
12331.
    
12332.
    
12333.
        /**
12334.
         * This property can be used to read data from any data source property,
12335.
         * including deeply nested objects / properties. `data` can be given in a
12336.
         * number of different ways which effect its behaviour:
12337.
         *
12338.
         * * `integer` - treated as an array index for the data source. This is the
12339.
         *   default that DataTables uses (incrementally increased for each column).
12340.
         * * `string` - read an object property from the data source. There are
12341.
         *   three 'special' options that can be used in the string to alter how
12342.
         *   DataTables reads the data from the source object:
12343.
         *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12344.
         *      Javascript to read from nested objects, so to can the options
12345.
         *      specified in `data`. For example: `browser.version` or
12346.
         *      `browser.name`. If your object parameter name contains a period, use
12347.
         *      `\\` to escape it - i.e. `first\\.name`.
12348.
         *    * `[]` - Array notation. DataTables can automatically combine data
12349.
         *      from and array source, joining the data with the characters provided
12350.
         *      between the two brackets. For example: `name[, ]` would provide a
12351.
         *      comma-space separated list from the source array. If no characters
12352.
         *      are provided between the brackets, the original array source is
12353.
         *      returned.
12354.
         *    * `()` - Function notation. Adding `()` to the end of a parameter will
12355.
         *      execute a function of the name given. For example: `browser()` for a
12356.
         *      simple function on the data source, `browser.version()` for a
12357.
         *      function in a nested property or even `browser().version` to get an
12358.
         *      object property if the function called returns an object. Note that
12359.
         *      function notation is recommended for use in `render` rather than
12360.
         *      `data` as it is much simpler to use as a renderer.
12361.
         * * `null` - use the original data source for the row rather than plucking
12362.
         *   data directly from it. This action has effects on two other
12363.
         *   initialisation options:
12364.
         *    * `defaultContent` - When null is given as the `data` option and
12365.
         *      `defaultContent` is specified for the column, the value defined by
12366.
         *      `defaultContent` will be used for the cell.
12367.
         *    * `render` - When null is used for the `data` option and the `render`
12368.
         *      option is specified for the column, the whole data source for the
12369.
         *      row is used for the renderer.
12370.
         * * `function` - the function given will be executed whenever DataTables
12371.
         *   needs to set or get the data for a cell in the column. The function
12372.
         *   takes three parameters:
12373.
         *    * Parameters:
12374.
         *      * `{array|object}` The data source for the row
12375.
         *      * `{string}` The type call data requested - this will be 'set' when
12376.
         *        setting data or 'filter', 'display', 'type', 'sort' or undefined
12377.
         *        when gathering data. Note that when `undefined` is given for the
12378.
         *        type DataTables expects to get the raw data for the object back<
12379.
         *      * `{*}` Data to set when the second parameter is 'set'.
12380.
         *    * Return:
12381.
         *      * The return value from the function is not required when 'set' is
12382.
         *        the type of call, but otherwise the return is what will be used
12383.
         *        for the data requested.
12384.
         *
12385.
         * Note that `data` is a getter and setter option. If you just require
12386.
         * formatting of data for output, you will likely want to use `render` which
12387.
         * is simply a getter and thus simpler to use.
12388.
         *
12389.
         * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12390.
         * name change reflects the flexibility of this property and is consistent
12391.
         * with the naming of mRender. If 'mDataProp' is given, then it will still
12392.
         * be used by DataTables, as it automatically maps the old name to the new
12393.
         * if required.
12394.
         *
12395.
         *  @type string|int|function|null
12396.
         *  @default null <i>Use automatically calculated column index</i>
12397.
         *
12398.
         *  @name DataTable.defaults.column.data
12399.
         *  @dtopt Columns
12400.
         *
12401.
         *  @example
12402.
         *    // Read table data from objects
12403.
         *    // JSON structure for each row:
12404.
         *    //   {
12405.
         *    //      "engine": {value},
12406.
         *    //      "browser": {value},
12407.
         *    //      "platform": {value},
12408.
         *    //      "version": {value},
12409.
         *    //      "grade": {value}
12410.
         *    //   }
12411.
         *    $(document).ready( function() {
12412.
         *      $('#example').dataTable( {
12413.
         *        "ajaxSource": "sources/objects.txt",
12414.
         *        "columns": [
12415.
         *          { "data": "engine" },
12416.
         *          { "data": "browser" },
12417.
         *          { "data": "platform" },
12418.
         *          { "data": "version" },
12419.
         *          { "data": "grade" }
12420.
         *        ]
12421.
         *      } );
12422.
         *    } );
12423.
         *
12424.
         *  @example
12425.
         *    // Read information from deeply nested objects
12426.
         *    // JSON structure for each row:
12427.
         *    //   {
12428.
         *    //      "engine": {value},
12429.
         *    //      "browser": {value},
12430.
         *    //      "platform": {
12431.
         *    //         "inner": {value}
12432.
         *    //      },
12433.
         *    //      "details": [
12434.
         *    //         {value}, {value}
12435.
         *    //      ]
12436.
         *    //   }
12437.
         *    $(document).ready( function() {
12438.
         *      $('#example').dataTable( {
12439.
         *        "ajaxSource": "sources/deep.txt",
12440.
         *        "columns": [
12441.
         *          { "data": "engine" },
12442.
         *          { "data": "browser" },
12443.
         *          { "data": "platform.inner" },
12444.
         *          { "data": "details.0" },
12445.
         *          { "data": "details.1" }
12446.
         *        ]
12447.
         *      } );
12448.
         *    } );
12449.
         *
12450.
         *  @example
12451.
         *    // Using `data` as a function to provide different information for
12452.
         *    // sorting, filtering and display. In this case, currency (price)
12453.
         *    $(document).ready( function() {
12454.
         *      $('#example').dataTable( {
12455.
         *        "columnDefs": [ {
12456.
         *          "targets": [ 0 ],
12457.
         *          "data": function ( source, type, val ) {
12458.
         *            if (type === 'set') {
12459.
         *              source.price = val;
12460.
         *              // Store the computed dislay and filter values for efficiency
12461.
         *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
12462.
         *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12463.
         *              return;
12464.
         *            }
12465.
         *            else if (type === 'display') {
12466.
         *              return source.price_display;
12467.
         *            }
12468.
         *            else if (type === 'filter') {
12469.
         *              return source.price_filter;
12470.
         *            }
12471.
         *            // 'sort', 'type' and undefined all just use the integer
12472.
         *            return source.price;
12473.
         *          }
12474.
         *        } ]
12475.
         *      } );
12476.
         *    } );
12477.
         *
12478.
         *  @example
12479.
         *    // Using default content
12480.
         *    $(document).ready( function() {
12481.
         *      $('#example').dataTable( {
12482.
         *        "columnDefs": [ {
12483.
         *          "targets": [ 0 ],
12484.
         *          "data": null,
12485.
         *          "defaultContent": "Click to edit"
12486.
         *        } ]
12487.
         *      } );
12488.
         *    } );
12489.
         *
12490.
         *  @example
12491.
         *    // Using array notation - outputting a list from an array
12492.
         *    $(document).ready( function() {
12493.
         *      $('#example').dataTable( {
12494.
         *        "columnDefs": [ {
12495.
         *          "targets": [ 0 ],
12496.
         *          "data": "name[, ]"
12497.
         *        } ]
12498.
         *      } );
12499.
         *    } );
12500.
         *
12501.
         */
12502.
        "mData": null,
12503.
    
12504.
    
12505.
        /**
12506.
         * This property is the rendering partner to `data` and it is suggested that
12507.
         * when you want to manipulate data for display (including filtering,
12508.
         * sorting etc) without altering the underlying data for the table, use this
12509.
         * property. `render` can be considered to be the the read only companion to
12510.
         * `data` which is read / write (then as such more complex). Like `data`
12511.
         * this option can be given in a number of different ways to effect its
12512.
         * behaviour:
12513.
         *
12514.
         * * `integer` - treated as an array index for the data source. This is the
12515.
         *   default that DataTables uses (incrementally increased for each column).
12516.
         * * `string` - read an object property from the data source. There are
12517.
         *   three 'special' options that can be used in the string to alter how
12518.
         *   DataTables reads the data from the source object:
12519.
         *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12520.
         *      Javascript to read from nested objects, so to can the options
12521.
         *      specified in `data`. For example: `browser.version` or
12522.
         *      `browser.name`. If your object parameter name contains a period, use
12523.
         *      `\\` to escape it - i.e. `first\\.name`.
12524.
         *    * `[]` - Array notation. DataTables can automatically combine data
12525.
         *      from and array source, joining the data with the characters provided
12526.
         *      between the two brackets. For example: `name[, ]` would provide a
12527.
         *      comma-space separated list from the source array. If no characters
12528.
         *      are provided between the brackets, the original array source is
12529.
         *      returned.
12530.
         *    * `()` - Function notation. Adding `()` to the end of a parameter will
12531.
         *      execute a function of the name given. For example: `browser()` for a
12532.
         *      simple function on the data source, `browser.version()` for a
12533.
         *      function in a nested property or even `browser().version` to get an
12534.
         *      object property if the function called returns an object.
12535.
         * * `object` - use different data for the different data types requested by
12536.
         *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
12537.
         *   of the object is the data type the property refers to and the value can
12538.
         *   defined using an integer, string or function using the same rules as
12539.
         *   `render` normally does. Note that an `_` option _must_ be specified.
12540.
         *   This is the default value to use if you haven't specified a value for
12541.
         *   the data type requested by DataTables.
12542.
         * * `function` - the function given will be executed whenever DataTables
12543.
         *   needs to set or get the data for a cell in the column. The function
12544.
         *   takes three parameters:
12545.
         *    * Parameters:
12546.
         *      * {array|object} The data source for the row (based on `data`)
12547.
         *      * {string} The type call data requested - this will be 'filter',
12548.
         *        'display', 'type' or 'sort'.
12549.
         *      * {array|object} The full data source for the row (not based on
12550.
         *        `data`)
12551.
         *    * Return:
12552.
         *      * The return value from the function is what will be used for the
12553.
         *        data requested.
12554.
         *
12555.
         *  @type string|int|function|object|null
12556.
         *  @default null Use the data source value.
12557.
         *
12558.
         *  @name DataTable.defaults.column.render
12559.
         *  @dtopt Columns
12560.
         *
12561.
         *  @example
12562.
         *    // Create a comma separated list from an array of objects
12563.
         *    $(document).ready( function() {
12564.
         *      $('#example').dataTable( {
12565.
         *        "ajaxSource": "sources/deep.txt",
12566.
         *        "columns": [
12567.
         *          { "data": "engine" },
12568.
         *          { "data": "browser" },
12569.
         *          {
12570.
         *            "data": "platform",
12571.
         *            "render": "[, ].name"
12572.
         *          }
12573.
         *        ]
12574.
         *      } );
12575.
         *    } );
12576.
         *
12577.
         *  @example
12578.
         *    // Execute a function to obtain data
12579.
         *    $(document).ready( function() {
12580.
         *      $('#example').dataTable( {
12581.
         *        "columnDefs": [ {
12582.
         *          "targets": [ 0 ],
12583.
         *          "data": null, // Use the full data source object for the renderer's source
12584.
         *          "render": "browserName()"
12585.
         *        } ]
12586.
         *      } );
12587.
         *    } );
12588.
         *
12589.
         *  @example
12590.
         *    // As an object, extracting different data for the different types
12591.
         *    // This would be used with a data source such as:
12592.
         *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12593.
         *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12594.
         *    // (which has both forms) is used for filtering for if a user inputs either format, while
12595.
         *    // the formatted phone number is the one that is shown in the table.
12596.
         *    $(document).ready( function() {
12597.
         *      $('#example').dataTable( {
12598.
         *        "columnDefs": [ {
12599.
         *          "targets": [ 0 ],
12600.
         *          "data": null, // Use the full data source object for the renderer's source
12601.
         *          "render": {
12602.
         *            "_": "phone",
12603.
         *            "filter": "phone_filter",
12604.
         *            "display": "phone_display"
12605.
         *          }
12606.
         *        } ]
12607.
         *      } );
12608.
         *    } );
12609.
         *
12610.
         *  @example
12611.
         *    // Use as a function to create a link from the data source
12612.
         *    $(document).ready( function() {
12613.
         *      $('#example').dataTable( {
12614.
         *        "columnDefs": [ {
12615.
         *          "targets": [ 0 ],
12616.
         *          "data": "download_link",
12617.
         *          "render": function ( data, type, full ) {
12618.
         *            return '<a href="'+data+'">Download</a>';
12619.
         *          }
12620.
         *        } ]
12621.
         *      } );
12622.
         *    } );
12623.
         */
12624.
        "mRender": null,
12625.
    
12626.
    
12627.
        /**
12628.
         * Change the cell type created for the column - either TD cells or TH cells. This
12629.
         * can be useful as TH cells have semantic meaning in the table body, allowing them
12630.
         * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12631.
         *  @type string
12632.
         *  @default td
12633.
         *
12634.
         *  @name DataTable.defaults.column.cellType
12635.
         *  @dtopt Columns
12636.
         *
12637.
         *  @example
12638.
         *    // Make the first column use TH cells
12639.
         *    $(document).ready( function() {
12640.
         *      $('#example').dataTable( {
12641.
         *        "columnDefs": [ {
12642.
         *          "targets": [ 0 ],
12643.
         *          "cellType": "th"
12644.
         *        } ]
12645.
         *      } );
12646.
         *    } );
12647.
         */
12648.
        "sCellType": "td",
12649.
    
12650.
    
12651.
        /**
12652.
         * Class to give to each cell in this column.
12653.
         *  @type string
12654.
         *  @default <i>Empty string</i>
12655.
         *
12656.
         *  @name DataTable.defaults.column.class
12657.
         *  @dtopt Columns
12658.
         *
12659.
         *  @example
12660.
         *    // Using `columnDefs`
12661.
         *    $(document).ready( function() {
12662.
         *      $('#example').dataTable( {
12663.
         *        "columnDefs": [
12664.
         *          { "class": "my_class", "targets": [ 0 ] }
12665.
         *        ]
12666.
         *      } );
12667.
         *    } );
12668.
         *
12669.
         *  @example
12670.
         *    // Using `columns`
12671.
         *    $(document).ready( function() {
12672.
         *      $('#example').dataTable( {
12673.
         *        "columns": [
12674.
         *          { "class": "my_class" },
12675.
         *          null,
12676.
         *          null,
12677.
         *          null,
12678.
         *          null
12679.
         *        ]
12680.
         *      } );
12681.
         *    } );
12682.
         */
12683.
        "sClass": "",
12684.
    
12685.
        /**
12686.
         * When DataTables calculates the column widths to assign to each column,
12687.
         * it finds the longest string in each column and then constructs a
12688.
         * temporary table and reads the widths from that. The problem with this
12689.
         * is that "mmm" is much wider then "iiii", but the latter is a longer
12690.
         * string - thus the calculation can go wrong (doing it properly and putting
12691.
         * it into an DOM object and measuring that is horribly(!) slow). Thus as
12692.
         * a "work around" we provide this option. It will append its value to the
12693.
         * text that is found to be the longest string for the column - i.e. padding.
12694.
         * Generally you shouldn't need this!
12695.
         *  @type string
12696.
         *  @default <i>Empty string<i>
12697.
         *
12698.
         *  @name DataTable.defaults.column.contentPadding
12699.
         *  @dtopt Columns
12700.
         *
12701.
         *  @example
12702.
         *    // Using `columns`
12703.
         *    $(document).ready( function() {
12704.
         *      $('#example').dataTable( {
12705.
         *        "columns": [
12706.
         *          null,
12707.
         *          null,
12708.
         *          null,
12709.
         *          {
12710.
         *            "contentPadding": "mmm"
12711.
         *          }
12712.
         *        ]
12713.
         *      } );
12714.
         *    } );
12715.
         */
12716.
        "sContentPadding": "",
12717.
    
12718.
    
12719.
        /**
12720.
         * Allows a default value to be given for a column's data, and will be used
12721.
         * whenever a null data source is encountered (this can be because `data`
12722.
         * is set to null, or because the data source itself is null).
12723.
         *  @type string
12724.
         *  @default null
12725.
         *
12726.
         *  @name DataTable.defaults.column.defaultContent
12727.
         *  @dtopt Columns
12728.
         *
12729.
         *  @example
12730.
         *    // Using `columnDefs`
12731.
         *    $(document).ready( function() {
12732.
         *      $('#example').dataTable( {
12733.
         *        "columnDefs": [
12734.
         *          {
12735.
         *            "data": null,
12736.
         *            "defaultContent": "Edit",
12737.
         *            "targets": [ -1 ]
12738.
         *          }
12739.
         *        ]
12740.
         *      } );
12741.
         *    } );
12742.
         *
12743.
         *  @example
12744.
         *    // Using `columns`
12745.
         *    $(document).ready( function() {
12746.
         *      $('#example').dataTable( {
12747.
         *        "columns": [
12748.
         *          null,
12749.
         *          null,
12750.
         *          null,
12751.
         *          {
12752.
         *            "data": null,
12753.
         *            "defaultContent": "Edit"
12754.
         *          }
12755.
         *        ]
12756.
         *      } );
12757.
         *    } );
12758.
         */
12759.
        "sDefaultContent": null,
12760.
    
12761.
    
12762.
        /**
12763.
         * This parameter is only used in DataTables' server-side processing. It can
12764.
         * be exceptionally useful to know what columns are being displayed on the
12765.
         * client side, and to map these to database fields. When defined, the names
12766.
         * also allow DataTables to reorder information from the server if it comes
12767.
         * back in an unexpected order (i.e. if you switch your columns around on the
12768.
         * client-side, your server-side code does not also need updating).
12769.
         *  @type string
12770.
         *  @default <i>Empty string</i>
12771.
         *
12772.
         *  @name DataTable.defaults.column.name
12773.
         *  @dtopt Columns
12774.
         *
12775.
         *  @example
12776.
         *    // Using `columnDefs`
12777.
         *    $(document).ready( function() {
12778.
         *      $('#example').dataTable( {
12779.
         *        "columnDefs": [
12780.
         *          { "name": "engine", "targets": [ 0 ] },
12781.
         *          { "name": "browser", "targets": [ 1 ] },
12782.
         *          { "name": "platform", "targets": [ 2 ] },
12783.
         *          { "name": "version", "targets": [ 3 ] },
12784.
         *          { "name": "grade", "targets": [ 4 ] }
12785.
         *        ]
12786.
         *      } );
12787.
         *    } );
12788.
         *
12789.
         *  @example
12790.
         *    // Using `columns`
12791.
         *    $(document).ready( function() {
12792.
         *      $('#example').dataTable( {
12793.
         *        "columns": [
12794.
         *          { "name": "engine" },
12795.
         *          { "name": "browser" },
12796.
         *          { "name": "platform" },
12797.
         *          { "name": "version" },
12798.
         *          { "name": "grade" }
12799.
         *        ]
12800.
         *      } );
12801.
         *    } );
12802.
         */
12803.
        "sName": "",
12804.
    
12805.
    
12806.
        /**
12807.
         * Defines a data source type for the ordering which can be used to read
12808.
         * real-time information from the table (updating the internally cached
12809.
         * version) prior to ordering. This allows ordering to occur on user
12810.
         * editable elements such as form inputs.
12811.
         *  @type string
12812.
         *  @default std
12813.
         *
12814.
         *  @name DataTable.defaults.column.orderDataType
12815.
         *  @dtopt Columns
12816.
         *
12817.
         *  @example
12818.
         *    // Using `columnDefs`
12819.
         *    $(document).ready( function() {
12820.
         *      $('#example').dataTable( {
12821.
         *        "columnDefs": [
12822.
         *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12823.
         *          { "type": "numeric", "targets": [ 3 ] },
12824.
         *          { "orderDataType": "dom-select", "targets": [ 4 ] },
12825.
         *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12826.
         *        ]
12827.
         *      } );
12828.
         *    } );
12829.
         *
12830.
         *  @example
12831.
         *    // Using `columns`
12832.
         *    $(document).ready( function() {
12833.
         *      $('#example').dataTable( {
12834.
         *        "columns": [
12835.
         *          null,
12836.
         *          null,
12837.
         *          { "orderDataType": "dom-text" },
12838.
         *          { "orderDataType": "dom-text", "type": "numeric" },
12839.
         *          { "orderDataType": "dom-select" },
12840.
         *          { "orderDataType": "dom-checkbox" }
12841.
         *        ]
12842.
         *      } );
12843.
         *    } );
12844.
         */
12845.
        "sSortDataType": "std",
12846.
    
12847.
    
12848.
        /**
12849.
         * The title of this column.
12850.
         *  @type string
12851.
         *  @default null <i>Derived from the 'TH' value for this column in the
12852.
         *    original HTML table.</i>
12853.
         *
12854.
         *  @name DataTable.defaults.column.title
12855.
         *  @dtopt Columns
12856.
         *
12857.
         *  @example
12858.
         *    // Using `columnDefs`
12859.
         *    $(document).ready( function() {
12860.
         *      $('#example').dataTable( {
12861.
         *        "columnDefs": [
12862.
         *          { "title": "My column title", "targets": [ 0 ] }
12863.
         *        ]
12864.
         *      } );
12865.
         *    } );
12866.
         *
12867.
         *  @example
12868.
         *    // Using `columns`
12869.
         *    $(document).ready( function() {
12870.
         *      $('#example').dataTable( {
12871.
         *        "columns": [
12872.
         *          { "title": "My column title" },
12873.
         *          null,
12874.
         *          null,
12875.
         *          null,
12876.
         *          null
12877.
         *        ]
12878.
         *      } );
12879.
         *    } );
12880.
         */
12881.
        "sTitle": null,
12882.
    
12883.
    
12884.
        /**
12885.
         * The type allows you to specify how the data for this column will be
12886.
         * ordered. Four types (string, numeric, date and html (which will strip
12887.
         * HTML tags before ordering)) are currently available. Note that only date
12888.
         * formats understood by Javascript's Date() object will be accepted as type
12889.
         * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12890.
         * 'numeric', 'date' or 'html' (by default). Further types can be adding
12891.
         * through plug-ins.
12892.
         *  @type string
12893.
         *  @default null <i>Auto-detected from raw data</i>
12894.
         *
12895.
         *  @name DataTable.defaults.column.type
12896.
         *  @dtopt Columns
12897.
         *
12898.
         *  @example
12899.
         *    // Using `columnDefs`
12900.
         *    $(document).ready( function() {
12901.
         *      $('#example').dataTable( {
12902.
         *        "columnDefs": [
12903.
         *          { "type": "html", "targets": [ 0 ] }
12904.
         *        ]
12905.
         *      } );
12906.
         *    } );
12907.
         *
12908.
         *  @example
12909.
         *    // Using `columns`
12910.
         *    $(document).ready( function() {
12911.
         *      $('#example').dataTable( {
12912.
         *        "columns": [
12913.
         *          { "type": "html" },
12914.
         *          null,
12915.
         *          null,
12916.
         *          null,
12917.
         *          null
12918.
         *        ]
12919.
         *      } );
12920.
         *    } );
12921.
         */
12922.
        "sType": null,
12923.
    
12924.
    
12925.
        /**
12926.
         * Defining the width of the column, this parameter may take any CSS value
12927.
         * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12928.
         * been given a specific width through this interface ensuring that the table
12929.
         * remains readable.
12930.
         *  @type string
12931.
         *  @default null <i>Automatic</i>
12932.
         *
12933.
         *  @name DataTable.defaults.column.width
12934.
         *  @dtopt Columns
12935.
         *
12936.
         *  @example
12937.
         *    // Using `columnDefs`
12938.
         *    $(document).ready( function() {
12939.
         *      $('#example').dataTable( {
12940.
         *        "columnDefs": [
12941.
         *          { "width": "20%", "targets": [ 0 ] }
12942.
         *        ]
12943.
         *      } );
12944.
         *    } );
12945.
         *
12946.
         *  @example
12947.
         *    // Using `columns`
12948.
         *    $(document).ready( function() {
12949.
         *      $('#example').dataTable( {
12950.
         *        "columns": [
12951.
         *          { "width": "20%" },
12952.
         *          null,
12953.
         *          null,
12954.
         *          null,
12955.
         *          null
12956.
         *        ]
12957.
         *      } );
12958.
         *    } );
12959.
         */
12960.
        "sWidth": null
12961.
    };
12962.
    
12963.
    _fnHungarianMap( DataTable.defaults.column );
12964.
    
12965.
    
12966.
    
12967.
    /**
12968.
     * DataTables settings object - this holds all the information needed for a
12969.
     * given table, including configuration, data and current application of the
12970.
     * table options. DataTables does not have a single instance for each DataTable
12971.
     * with the settings attached to that instance, but rather instances of the
12972.
     * DataTable "class" are created on-the-fly as needed (typically by a
12973.
     * $().dataTable() call) and the settings object is then applied to that
12974.
     * instance.
12975.
     *
12976.
     * Note that this object is related to {@link DataTable.defaults} but this
12977.
     * one is the internal data store for DataTables's cache of columns. It should
12978.
     * NOT be manipulated outside of DataTables. Any configuration should be done
12979.
     * through the initialisation options.
12980.
     *  @namespace
12981.
     *  @todo Really should attach the settings object to individual instances so we
12982.
     *    don't need to create new instances on each $().dataTable() call (if the
12983.
     *    table already exists). It would also save passing oSettings around and
12984.
     *    into every single function. However, this is a very significant
12985.
     *    architecture change for DataTables and will almost certainly break
12986.
     *    backwards compatibility with older installations. This is something that
12987.
     *    will be done in 2.0.
12988.
     */
12989.
    DataTable.models.oSettings = {
12990.
        /**
12991.
         * Primary features of DataTables and their enablement state.
12992.
         *  @namespace
12993.
         */
12994.
        "oFeatures": {
12995.
    
12996.
            /**
12997.
             * Flag to say if DataTables should automatically try to calculate the
12998.
             * optimum table and columns widths (true) or not (false).
12999.
             * Note that this parameter will be set by the initialisation routine. To
13000.
             * set a default use {@link DataTable.defaults}.
13001.
             *  @type boolean
13002.
             */
13003.
            "bAutoWidth": null,
13004.
    
13005.
            /**
13006.
             * Delay the creation of TR and TD elements until they are actually
13007.
             * needed by a driven page draw. This can give a significant speed
13008.
             * increase for Ajax source and Javascript source data, but makes no
13009.
             * difference at all fro DOM and server-side processing tables.
13010.
             * Note that this parameter will be set by the initialisation routine. To
13011.
             * set a default use {@link DataTable.defaults}.
13012.
             *  @type boolean
13013.
             */
13014.
            "bDeferRender": null,
13015.
    
13016.
            /**
13017.
             * Enable filtering on the table or not. Note that if this is disabled
13018.
             * then there is no filtering at all on the table, including fnFilter.
13019.
             * To just remove the filtering input use sDom and remove the 'f' option.
13020.
             * Note that this parameter will be set by the initialisation routine. To
13021.
             * set a default use {@link DataTable.defaults}.
13022.
             *  @type boolean
13023.
             */
13024.
            "bFilter": null,
13025.
    
13026.
            /**
13027.
             * Table information element (the 'Showing x of y records' div) enable
13028.
             * flag.
13029.
             * Note that this parameter will be set by the initialisation routine. To
13030.
             * set a default use {@link DataTable.defaults}.
13031.
             *  @type boolean
13032.
             */
13033.
            "bInfo": null,
13034.
    
13035.
            /**
13036.
             * Present a user control allowing the end user to change the page size
13037.
             * when pagination is enabled.
13038.
             * Note that this parameter will be set by the initialisation routine. To
13039.
             * set a default use {@link DataTable.defaults}.
13040.
             *  @type boolean
13041.
             */
13042.
            "bLengthChange": null,
13043.
    
13044.
            /**
13045.
             * Pagination enabled or not. Note that if this is disabled then length
13046.
             * changing must also be disabled.
13047.
             * Note that this parameter will be set by the initialisation routine. To
13048.
             * set a default use {@link DataTable.defaults}.
13049.
             *  @type boolean
13050.
             */
13051.
            "bPaginate": null,
13052.
    
13053.
            /**
13054.
             * Processing indicator enable flag whenever DataTables is enacting a
13055.
             * user request - typically an Ajax request for server-side processing.
13056.
             * Note that this parameter will be set by the initialisation routine. To
13057.
             * set a default use {@link DataTable.defaults}.
13058.
             *  @type boolean
13059.
             */
13060.
            "bProcessing": null,
13061.
    
13062.
            /**
13063.
             * Server-side processing enabled flag - when enabled DataTables will
13064.
             * get all data from the server for every draw - there is no filtering,
13065.
             * sorting or paging done on the client-side.
13066.
             * Note that this parameter will be set by the initialisation routine. To
13067.
             * set a default use {@link DataTable.defaults}.
13068.
             *  @type boolean
13069.
             */
13070.
            "bServerSide": null,
13071.
    
13072.
            /**
13073.
             * Sorting enablement flag.
13074.
             * Note that this parameter will be set by the initialisation routine. To
13075.
             * set a default use {@link DataTable.defaults}.
13076.
             *  @type boolean
13077.
             */
13078.
            "bSort": null,
13079.
    
13080.
            /**
13081.
             * Multi-column sorting
13082.
             * Note that this parameter will be set by the initialisation routine. To
13083.
             * set a default use {@link DataTable.defaults}.
13084.
             *  @type boolean
13085.
             */
13086.
            "bSortMulti": null,
13087.
    
13088.
            /**
13089.
             * Apply a class to the columns which are being sorted to provide a
13090.
             * visual highlight or not. This can slow things down when enabled since
13091.
             * there is a lot of DOM interaction.
13092.
             * Note that this parameter will be set by the initialisation routine. To
13093.
             * set a default use {@link DataTable.defaults}.
13094.
             *  @type boolean
13095.
             */
13096.
            "bSortClasses": null,
13097.
    
13098.
            /**
13099.
             * State saving enablement flag.
13100.
             * Note that this parameter will be set by the initialisation routine. To
13101.
             * set a default use {@link DataTable.defaults}.
13102.
             *  @type boolean
13103.
             */
13104.
            "bStateSave": null
13105.
        },
13106.
    
13107.
    
13108.
        /**
13109.
         * Scrolling settings for a table.
13110.
         *  @namespace
13111.
         */
13112.
        "oScroll": {
13113.
            /**
13114.
             * When the table is shorter in height than sScrollY, collapse the
13115.
             * table container down to the height of the table (when true).
13116.
             * Note that this parameter will be set by the initialisation routine. To
13117.
             * set a default use {@link DataTable.defaults}.
13118.
             *  @type boolean
13119.
             */
13120.
            "bCollapse": null,
13121.
    
13122.
            /**
13123.
             * Width of the scrollbar for the web-browser's platform. Calculated
13124.
             * during table initialisation.
13125.
             *  @type int
13126.
             *  @default 0
13127.
             */
13128.
            "iBarWidth": 0,
13129.
    
13130.
            /**
13131.
             * Viewport width for horizontal scrolling. Horizontal scrolling is
13132.
             * disabled if an empty string.
13133.
             * Note that this parameter will be set by the initialisation routine. To
13134.
             * set a default use {@link DataTable.defaults}.
13135.
             *  @type string
13136.
             */
13137.
            "sX": null,
13138.
    
13139.
            /**
13140.
             * Width to expand the table to when using x-scrolling. Typically you
13141.
             * should not need to use this.
13142.
             * Note that this parameter will be set by the initialisation routine. To
13143.
             * set a default use {@link DataTable.defaults}.
13144.
             *  @type string
13145.
             *  @deprecated
13146.
             */
13147.
            "sXInner": null,
13148.
    
13149.
            /**
13150.
             * Viewport height for vertical scrolling. Vertical scrolling is disabled
13151.
             * if an empty string.
13152.
             * Note that this parameter will be set by the initialisation routine. To
13153.
             * set a default use {@link DataTable.defaults}.
13154.
             *  @type string
13155.
             */
13156.
            "sY": null
13157.
        },
13158.
    
13159.
        /**
13160.
         * Language information for the table.
13161.
         *  @namespace
13162.
         *  @extends DataTable.defaults.oLanguage
13163.
         */
13164.
        "oLanguage": {
13165.
            /**
13166.
             * Information callback function. See
13167.
             * {@link DataTable.defaults.fnInfoCallback}
13168.
             *  @type function
13169.
             *  @default null
13170.
             */
13171.
            "fnInfoCallback": null
13172.
        },
13173.
    
13174.
        /**
13175.
         * Browser support parameters
13176.
         *  @namespace
13177.
         */
13178.
        "oBrowser": {
13179.
            /**
13180.
             * Indicate if the browser incorrectly calculates width:100% inside a
13181.
             * scrolling element (IE6/7)
13182.
             *  @type boolean
13183.
             *  @default false
13184.
             */
13185.
            "bScrollOversize": false,
13186.
    
13187.
            /**
13188.
             * Determine if the vertical scrollbar is on the right or left of the
13189.
             * scrolling container - needed for rtl language layout, although not
13190.
             * all browsers move the scrollbar (Safari).
13191.
             *  @type boolean
13192.
             *  @default false
13193.
             */
13194.
            "bScrollbarLeft": false,
13195.
    
13196.
            /**
13197.
             * Flag for if `getBoundingClientRect` is fully supported or not
13198.
             *  @type boolean
13199.
             *  @default false
13200.
             */
13201.
            "bBounding": false,
13202.
    
13203.
            /**
13204.
             * Browser scrollbar width
13205.
             *  @type integer
13206.
             *  @default 0
13207.
             */
13208.
            "barWidth": 0
13209.
        },
13210.
    
13211.
    
13212.
        "ajax": null,
13213.
    
13214.
    
13215.
        /**
13216.
         * Array referencing the nodes which are used for the features. The
13217.
         * parameters of this object match what is allowed by sDom - i.e.
13218.
         *   <ul>
13219.
         *     <li>'l' - Length changing</li>
13220.
         *     <li>'f' - Filtering input</li>
13221.
         *     <li>'t' - The table!</li>
13222.
         *     <li>'i' - Information</li>
13223.
         *     <li>'p' - Pagination</li>
13224.
         *     <li>'r' - pRocessing</li>
13225.
         *   </ul>
13226.
         *  @type array
13227.
         *  @default []
13228.
         */
13229.
        "aanFeatures": [],
13230.
    
13231.
        /**
13232.
         * Store data information - see {@link DataTable.models.oRow} for detailed
13233.
         * information.
13234.
         *  @type array
13235.
         *  @default []
13236.
         */
13237.
        "aoData": [],
13238.
    
13239.
        /**
13240.
         * Array of indexes which are in the current display (after filtering etc)
13241.
         *  @type array
13242.
         *  @default []
13243.
         */
13244.
        "aiDisplay": [],
13245.
    
13246.
        /**
13247.
         * Array of indexes for display - no filtering
13248.
         *  @type array
13249.
         *  @default []
13250.
         */
13251.
        "aiDisplayMaster": [],
13252.
    
13253.
        /**
13254.
         * Map of row ids to data indexes
13255.
         *  @type object
13256.
         *  @default {}
13257.
         */
13258.
        "aIds": {},
13259.
    
13260.
        /**
13261.
         * Store information about each column that is in use
13262.
         *  @type array
13263.
         *  @default []
13264.
         */
13265.
        "aoColumns": [],
13266.
    
13267.
        /**
13268.
         * Store information about the table's header
13269.
         *  @type array
13270.
         *  @default []
13271.
         */
13272.
        "aoHeader": [],
13273.
    
13274.
        /**
13275.
         * Store information about the table's footer
13276.
         *  @type array
13277.
         *  @default []
13278.
         */
13279.
        "aoFooter": [],
13280.
    
13281.
        /**
13282.
         * Store the applied global search information in case we want to force a
13283.
         * research or compare the old search to a new one.
13284.
         * Note that this parameter will be set by the initialisation routine. To
13285.
         * set a default use {@link DataTable.defaults}.
13286.
         *  @namespace
13287.
         *  @extends DataTable.models.oSearch
13288.
         */
13289.
        "oPreviousSearch": {},
13290.
    
13291.
        /**
13292.
         * Store the applied search for each column - see
13293.
         * {@link DataTable.models.oSearch} for the format that is used for the
13294.
         * filtering information for each column.
13295.
         *  @type array
13296.
         *  @default []
13297.
         */
13298.
        "aoPreSearchCols": [],
13299.
    
13300.
        /**
13301.
         * Sorting that is applied to the table. Note that the inner arrays are
13302.
         * used in the following manner:
13303.
         * <ul>
13304.
         *   <li>Index 0 - column number</li>
13305.
         *   <li>Index 1 - current sorting direction</li>
13306.
         * </ul>
13307.
         * Note that this parameter will be set by the initialisation routine. To
13308.
         * set a default use {@link DataTable.defaults}.
13309.
         *  @type array
13310.
         *  @todo These inner arrays should really be objects
13311.
         */
13312.
        "aaSorting": null,
13313.
    
13314.
        /**
13315.
         * Sorting that is always applied to the table (i.e. prefixed in front of
13316.
         * aaSorting).
13317.
         * Note that this parameter will be set by the initialisation routine. To
13318.
         * set a default use {@link DataTable.defaults}.
13319.
         *  @type array
13320.
         *  @default []
13321.
         */
13322.
        "aaSortingFixed": [],
13323.
    
13324.
        /**
13325.
         * Classes to use for the striping of a table.
13326.
         * Note that this parameter will be set by the initialisation routine. To
13327.
         * set a default use {@link DataTable.defaults}.
13328.
         *  @type array
13329.
         *  @default []
13330.
         */
13331.
        "asStripeClasses": null,
13332.
    
13333.
        /**
13334.
         * If restoring a table - we should restore its striping classes as well
13335.
         *  @type array
13336.
         *  @default []
13337.
         */
13338.
        "asDestroyStripes": [],
13339.
    
13340.
        /**
13341.
         * If restoring a table - we should restore its width
13342.
         *  @type int
13343.
         *  @default 0
13344.
         */
13345.
        "sDestroyWidth": 0,
13346.
    
13347.
        /**
13348.
         * Callback functions array for every time a row is inserted (i.e. on a draw).
13349.
         *  @type array
13350.
         *  @default []
13351.
         */
13352.
        "aoRowCallback": [],
13353.
    
13354.
        /**
13355.
         * Callback functions for the header on each draw.
13356.
         *  @type array
13357.
         *  @default []
13358.
         */
13359.
        "aoHeaderCallback": [],
13360.
    
13361.
        /**
13362.
         * Callback function for the footer on each draw.
13363.
         *  @type array
13364.
         *  @default []
13365.
         */
13366.
        "aoFooterCallback": [],
13367.
    
13368.
        /**
13369.
         * Array of callback functions for draw callback functions
13370.
         *  @type array
13371.
         *  @default []
13372.
         */
13373.
        "aoDrawCallback": [],
13374.
    
13375.
        /**
13376.
         * Array of callback functions for row created function
13377.
         *  @type array
13378.
         *  @default []
13379.
         */
13380.
        "aoRowCreatedCallback": [],
13381.
    
13382.
        /**
13383.
         * Callback functions for just before the table is redrawn. A return of
13384.
         * false will be used to cancel the draw.
13385.
         *  @type array
13386.
         *  @default []
13387.
         */
13388.
        "aoPreDrawCallback": [],
13389.
    
13390.
        /**
13391.
         * Callback functions for when the table has been initialised.
13392.
         *  @type array
13393.
         *  @default []
13394.
         */
13395.
        "aoInitComplete": [],
13396.
    
13397.
    
13398.
        /**
13399.
         * Callbacks for modifying the settings to be stored for state saving, prior to
13400.
         * saving state.
13401.
         *  @type array
13402.
         *  @default []
13403.
         */
13404.
        "aoStateSaveParams": [],
13405.
    
13406.
        /**
13407.
         * Callbacks for modifying the settings that have been stored for state saving
13408.
         * prior to using the stored values to restore the state.
13409.
         *  @type array
13410.
         *  @default []
13411.
         */
13412.
        "aoStateLoadParams": [],
13413.
    
13414.
        /**
13415.
         * Callbacks for operating on the settings object once the saved state has been
13416.
         * loaded
13417.
         *  @type array
13418.
         *  @default []
13419.
         */
13420.
        "aoStateLoaded": [],
13421.
    
13422.
        /**
13423.
         * Cache the table ID for quick access
13424.
         *  @type string
13425.
         *  @default <i>Empty string</i>
13426.
         */
13427.
        "sTableId": "",
13428.
    
13429.
        /**
13430.
         * The TABLE node for the main table
13431.
         *  @type node
13432.
         *  @default null
13433.
         */
13434.
        "nTable": null,
13435.
    
13436.
        /**
13437.
         * Permanent ref to the thead element
13438.
         *  @type node
13439.
         *  @default null
13440.
         */
13441.
        "nTHead": null,
13442.
    
13443.
        /**
13444.
         * Permanent ref to the tfoot element - if it exists
13445.
         *  @type node
13446.
         *  @default null
13447.
         */
13448.
        "nTFoot": null,
13449.
    
13450.
        /**
13451.
         * Permanent ref to the tbody element
13452.
         *  @type node
13453.
         *  @default null
13454.
         */
13455.
        "nTBody": null,
13456.
    
13457.
        /**
13458.
         * Cache the wrapper node (contains all DataTables controlled elements)
13459.
         *  @type node
13460.
         *  @default null
13461.
         */
13462.
        "nTableWrapper": null,
13463.
    
13464.
        /**
13465.
         * Indicate if when using server-side processing the loading of data
13466.
         * should be deferred until the second draw.
13467.
         * Note that this parameter will be set by the initialisation routine. To
13468.
         * set a default use {@link DataTable.defaults}.
13469.
         *  @type boolean
13470.
         *  @default false
13471.
         */
13472.
        "bDeferLoading": false,
13473.
    
13474.
        /**
13475.
         * Indicate if all required information has been read in
13476.
         *  @type boolean
13477.
         *  @default false
13478.
         */
13479.
        "bInitialised": false,
13480.
    
13481.
        /**
13482.
         * Information about open rows. Each object in the array has the parameters
13483.
         * 'nTr' and 'nParent'
13484.
         *  @type array
13485.
         *  @default []
13486.
         */
13487.
        "aoOpenRows": [],
13488.
    
13489.
        /**
13490.
         * Dictate the positioning of DataTables' control elements - see
13491.
         * {@link DataTable.model.oInit.sDom}.
13492.
         * Note that this parameter will be set by the initialisation routine. To
13493.
         * set a default use {@link DataTable.defaults}.
13494.
         *  @type string
13495.
         *  @default null
13496.
         */
13497.
        "sDom": null,
13498.
    
13499.
        /**
13500.
         * Search delay (in mS)
13501.
         *  @type integer
13502.
         *  @default null
13503.
         */
13504.
        "searchDelay": null,
13505.
    
13506.
        /**
13507.
         * Which type of pagination should be used.
13508.
         * Note that this parameter will be set by the initialisation routine. To
13509.
         * set a default use {@link DataTable.defaults}.
13510.
         *  @type string
13511.
         *  @default two_button
13512.
         */
13513.
        "sPaginationType": "two_button",
13514.
    
13515.
        /**
13516.
         * The state duration (for `stateSave`) in seconds.
13517.
         * Note that this parameter will be set by the initialisation routine. To
13518.
         * set a default use {@link DataTable.defaults}.
13519.
         *  @type int
13520.
         *  @default 0
13521.
         */
13522.
        "iStateDuration": 0,
13523.
    
13524.
        /**
13525.
         * Array of callback functions for state saving. Each array element is an
13526.
         * object with the following parameters:
13527.
         *   <ul>
13528.
         *     <li>function:fn - function to call. Takes two parameters, oSettings
13529.
         *       and the JSON string to save that has been thus far created. Returns
13530.
         *       a JSON string to be inserted into a json object
13531.
         *       (i.e. '"param": [ 0, 1, 2]')</li>
13532.
         *     <li>string:sName - name of callback</li>
13533.
         *   </ul>
13534.
         *  @type array
13535.
         *  @default []
13536.
         */
13537.
        "aoStateSave": [],
13538.
    
13539.
        /**
13540.
         * Array of callback functions for state loading. Each array element is an
13541.
         * object with the following parameters:
13542.
         *   <ul>
13543.
         *     <li>function:fn - function to call. Takes two parameters, oSettings
13544.
         *       and the object stored. May return false to cancel state loading</li>
13545.
         *     <li>string:sName - name of callback</li>
13546.
         *   </ul>
13547.
         *  @type array
13548.
         *  @default []
13549.
         */
13550.
        "aoStateLoad": [],
13551.
    
13552.
        /**
13553.
         * State that was saved. Useful for back reference
13554.
         *  @type object
13555.
         *  @default null
13556.
         */
13557.
        "oSavedState": null,
13558.
    
13559.
        /**
13560.
         * State that was loaded. Useful for back reference
13561.
         *  @type object
13562.
         *  @default null
13563.
         */
13564.
        "oLoadedState": null,
13565.
    
13566.
        /**
13567.
         * Source url for AJAX data for the table.
13568.
         * Note that this parameter will be set by the initialisation routine. To
13569.
         * set a default use {@link DataTable.defaults}.
13570.
         *  @type string
13571.
         *  @default null
13572.
         */
13573.
        "sAjaxSource": null,
13574.
    
13575.
        /**
13576.
         * Property from a given object from which to read the table data from. This
13577.
         * can be an empty string (when not server-side processing), in which case
13578.
         * it is  assumed an an array is given directly.
13579.
         * Note that this parameter will be set by the initialisation routine. To
13580.
         * set a default use {@link DataTable.defaults}.
13581.
         *  @type string
13582.
         */
13583.
        "sAjaxDataProp": null,
13584.
    
13585.
        /**
13586.
         * Note if draw should be blocked while getting data
13587.
         *  @type boolean
13588.
         *  @default true
13589.
         */
13590.
        "bAjaxDataGet": true,
13591.
    
13592.
        /**
13593.
         * The last jQuery XHR object that was used for server-side data gathering.
13594.
         * This can be used for working with the XHR information in one of the
13595.
         * callbacks
13596.
         *  @type object
13597.
         *  @default null
13598.
         */
13599.
        "jqXHR": null,
13600.
    
13601.
        /**
13602.
         * JSON returned from the server in the last Ajax request
13603.
         *  @type object
13604.
         *  @default undefined
13605.
         */
13606.
        "json": undefined,
13607.
    
13608.
        /**
13609.
         * Data submitted as part of the last Ajax request
13610.
         *  @type object
13611.
         *  @default undefined
13612.
         */
13613.
        "oAjaxData": undefined,
13614.
    
13615.
        /**
13616.
         * Function to get the server-side data.
13617.
         * Note that this parameter will be set by the initialisation routine. To
13618.
         * set a default use {@link DataTable.defaults}.
13619.
         *  @type function
13620.
         */
13621.
        "fnServerData": null,
13622.
    
13623.
        /**
13624.
         * Functions which are called prior to sending an Ajax request so extra
13625.
         * parameters can easily be sent to the server
13626.
         *  @type array
13627.
         *  @default []
13628.
         */
13629.
        "aoServerParams": [],
13630.
    
13631.
        /**
13632.
         * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13633.
         * required).
13634.
         * Note that this parameter will be set by the initialisation routine. To
13635.
         * set a default use {@link DataTable.defaults}.
13636.
         *  @type string
13637.
         */
13638.
        "sServerMethod": null,
13639.
    
13640.
        /**
13641.
         * Format numbers for display.
13642.
         * Note that this parameter will be set by the initialisation routine. To
13643.
         * set a default use {@link DataTable.defaults}.
13644.
         *  @type function
13645.
         */
13646.
        "fnFormatNumber": null,
13647.
    
13648.
        /**
13649.
         * List of options that can be used for the user selectable length menu.
13650.
         * Note that this parameter will be set by the initialisation routine. To
13651.
         * set a default use {@link DataTable.defaults}.
13652.
         *  @type array
13653.
         *  @default []
13654.
         */
13655.
        "aLengthMenu": null,
13656.
    
13657.
        /**
13658.
         * Counter for the draws that the table does. Also used as a tracker for
13659.
         * server-side processing
13660.
         *  @type int
13661.
         *  @default 0
13662.
         */
13663.
        "iDraw": 0,
13664.
    
13665.
        /**
13666.
         * Indicate if a redraw is being done - useful for Ajax
13667.
         *  @type boolean
13668.
         *  @default false
13669.
         */
13670.
        "bDrawing": false,
13671.
    
13672.
        /**
13673.
         * Draw index (iDraw) of the last error when parsing the returned data
13674.
         *  @type int
13675.
         *  @default -1
13676.
         */
13677.
        "iDrawError": -1,
13678.
    
13679.
        /**
13680.
         * Paging display length
13681.
         *  @type int
13682.
         *  @default 10
13683.
         */
13684.
        "_iDisplayLength": 10,
13685.
    
13686.
        /**
13687.
         * Paging start point - aiDisplay index
13688.
         *  @type int
13689.
         *  @default 0
13690.
         */
13691.
        "_iDisplayStart": 0,
13692.
    
13693.
        /**
13694.
         * Server-side processing - number of records in the result set
13695.
         * (i.e. before filtering), Use fnRecordsTotal rather than
13696.
         * this property to get the value of the number of records, regardless of
13697.
         * the server-side processing setting.
13698.
         *  @type int
13699.
         *  @default 0
13700.
         *  @private
13701.
         */
13702.
        "_iRecordsTotal": 0,
13703.
    
13704.
        /**
13705.
         * Server-side processing - number of records in the current display set
13706.
         * (i.e. after filtering). Use fnRecordsDisplay rather than
13707.
         * this property to get the value of the number of records, regardless of
13708.
         * the server-side processing setting.
13709.
         *  @type boolean
13710.
         *  @default 0
13711.
         *  @private
13712.
         */
13713.
        "_iRecordsDisplay": 0,
13714.
    
13715.
        /**
13716.
         * The classes to use for the table
13717.
         *  @type object
13718.
         *  @default {}
13719.
         */
13720.
        "oClasses": {},
13721.
    
13722.
        /**
13723.
         * Flag attached to the settings object so you can check in the draw
13724.
         * callback if filtering has been done in the draw. Deprecated in favour of
13725.
         * events.
13726.
         *  @type boolean
13727.
         *  @default false
13728.
         *  @deprecated
13729.
         */
13730.
        "bFiltered": false,
13731.
    
13732.
        /**
13733.
         * Flag attached to the settings object so you can check in the draw
13734.
         * callback if sorting has been done in the draw. Deprecated in favour of
13735.
         * events.
13736.
         *  @type boolean
13737.
         *  @default false
13738.
         *  @deprecated
13739.
         */
13740.
        "bSorted": false,
13741.
    
13742.
        /**
13743.
         * Indicate that if multiple rows are in the header and there is more than
13744.
         * one unique cell per column, if the top one (true) or bottom one (false)
13745.
         * should be used for sorting / title by DataTables.
13746.
         * Note that this parameter will be set by the initialisation routine. To
13747.
         * set a default use {@link DataTable.defaults}.
13748.
         *  @type boolean
13749.
         */
13750.
        "bSortCellsTop": null,
13751.
    
13752.
        /**
13753.
         * Initialisation object that is used for the table
13754.
         *  @type object
13755.
         *  @default null
13756.
         */
13757.
        "oInit": null,
13758.
    
13759.
        /**
13760.
         * Destroy callback functions - for plug-ins to attach themselves to the
13761.
         * destroy so they can clean up markup and events.
13762.
         *  @type array
13763.
         *  @default []
13764.
         */
13765.
        "aoDestroyCallback": [],
13766.
    
13767.
    
13768.
        /**
13769.
         * Get the number of records in the current record set, before filtering
13770.
         *  @type function
13771.
         */
13772.
        "fnRecordsTotal": function ()
13773.
        {
13774.
            return _fnDataSource( this ) == 'ssp' ?
13775.
                this._iRecordsTotal * 1 :
13776.
                this.aiDisplayMaster.length;
13777.
        },
13778.
    
13779.
        /**
13780.
         * Get the number of records in the current record set, after filtering
13781.
         *  @type function
13782.
         */
13783.
        "fnRecordsDisplay": function ()
13784.
        {
13785.
            return _fnDataSource( this ) == 'ssp' ?
13786.
                this._iRecordsDisplay * 1 :
13787.
                this.aiDisplay.length;
13788.
        },
13789.
    
13790.
        /**
13791.
         * Get the display end point - aiDisplay index
13792.
         *  @type function
13793.
         */
13794.
        "fnDisplayEnd": function ()
13795.
        {
13796.
            var
13797.
                len      = this._iDisplayLength,
13798.
                start    = this._iDisplayStart,
13799.
                calc     = start + len,
13800.
                records  = this.aiDisplay.length,
13801.
                features = this.oFeatures,
13802.
                paginate = features.bPaginate;
13803.
    
13804.
            if ( features.bServerSide ) {
13805.
                return paginate === false || len === -1 ?
13806.
                    start + records :
13807.
                    Math.min( start+len, this._iRecordsDisplay );
13808.
            }
13809.
            else {
13810.
                return ! paginate || calc>records || len===-1 ?
13811.
                    records :
13812.
                    calc;
13813.
            }
13814.
        },
13815.
    
13816.
        /**
13817.
         * The DataTables object for this table
13818.
         *  @type object
13819.
         *  @default null
13820.
         */
13821.
        "oInstance": null,
13822.
    
13823.
        /**
13824.
         * Unique identifier for each instance of the DataTables object. If there
13825.
         * is an ID on the table node, then it takes that value, otherwise an
13826.
         * incrementing internal counter is used.
13827.
         *  @type string
13828.
         *  @default null
13829.
         */
13830.
        "sInstance": null,
13831.
    
13832.
        /**
13833.
         * tabindex attribute value that is added to DataTables control elements, allowing
13834.
         * keyboard navigation of the table and its controls.
13835.
         */
13836.
        "iTabIndex": 0,
13837.
    
13838.
        /**
13839.
         * DIV container for the footer scrolling table if scrolling
13840.
         */
13841.
        "nScrollHead": null,
13842.
    
13843.
        /**
13844.
         * DIV container for the footer scrolling table if scrolling
13845.
         */
13846.
        "nScrollFoot": null,
13847.
    
13848.
        /**
13849.
         * Last applied sort
13850.
         *  @type array
13851.
         *  @default []
13852.
         */
13853.
        "aLastSort": [],
13854.
    
13855.
        /**
13856.
         * Stored plug-in instances
13857.
         *  @type object
13858.
         *  @default {}
13859.
         */
13860.
        "oPlugins": {},
13861.
    
13862.
        /**
13863.
         * Function used to get a row's id from the row's data
13864.
         *  @type function
13865.
         *  @default null
13866.
         */
13867.
        "rowIdFn": null,
13868.
    
13869.
        /**
13870.
         * Data location where to store a row's id
13871.
         *  @type string
13872.
         *  @default null
13873.
         */
13874.
        "rowId": null
13875.
    };
13876.
 
13877.
    /**
13878.
     * Extension object for DataTables that is used to provide all extension
13879.
     * options.
13880.
     *
13881.
     * Note that the `DataTable.ext` object is available through
13882.
     * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13883.
     * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13884.
     *  @namespace
13885.
     *  @extends DataTable.models.ext
13886.
     */
13887.
    
13888.
    
13889.
    /**
13890.
     * DataTables extensions
13891.
     * 
13892.
     * This namespace acts as a collection area for plug-ins that can be used to
13893.
     * extend DataTables capabilities. Indeed many of the build in methods
13894.
     * use this method to provide their own capabilities (sorting methods for
13895.
     * example).
13896.
     *
13897.
     * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13898.
     * reasons
13899.
     *
13900.
     *  @namespace
13901.
     */
13902.
    DataTable.ext = _ext = {
13903.
        /**
13904.
         * Buttons. For use with the Buttons extension for DataTables. This is
13905.
         * defined here so other extensions can define buttons regardless of load
13906.
         * order. It is _not_ used by DataTables core.
13907.
         *
13908.
         *  @type object
13909.
         *  @default {}
13910.
         */
13911.
        buttons: {},
13912.
    
13913.
    
13914.
        /**
13915.
         * Element class names
13916.
         *
13917.
         *  @type object
13918.
         *  @default {}
13919.
         */
13920.
        classes: {},
13921.
    
13922.
    
13923.
        /**
13924.
         * DataTables build type (expanded by the download builder)
13925.
         *
13926.
         *  @type string
13927.
         */
13928.
        builder: "-source-",
13929.
    
13930.
    
13931.
        /**
13932.
         * Error reporting.
13933.
         * 
13934.
         * How should DataTables report an error. Can take the value 'alert',
13935.
         * 'throw', 'none' or a function.
13936.
         *
13937.
         *  @type string|function
13938.
         *  @default alert
13939.
         */
13940.
        errMode: "alert",
13941.
    
13942.
    
13943.
        /**
13944.
         * Feature plug-ins.
13945.
         * 
13946.
         * This is an array of objects which describe the feature plug-ins that are
13947.
         * available to DataTables. These feature plug-ins are then available for
13948.
         * use through the `dom` initialisation option.
13949.
         * 
13950.
         * Each feature plug-in is described by an object which must have the
13951.
         * following properties:
13952.
         * 
13953.
         * * `fnInit` - function that is used to initialise the plug-in,
13954.
         * * `cFeature` - a character so the feature can be enabled by the `dom`
13955.
         *   instillation option. This is case sensitive.
13956.
         *
13957.
         * The `fnInit` function has the following input parameters:
13958.
         *
13959.
         * 1. `{object}` DataTables settings object: see
13960.
         *    {@link DataTable.models.oSettings}
13961.
         *
13962.
         * And the following return is expected:
13963.
         * 
13964.
         * * {node|null} The element which contains your feature. Note that the
13965.
         *   return may also be void if your plug-in does not require to inject any
13966.
         *   DOM elements into DataTables control (`dom`) - for example this might
13967.
         *   be useful when developing a plug-in which allows table control via
13968.
         *   keyboard entry
13969.
         *
13970.
         *  @type array
13971.
         *
13972.
         *  @example
13973.
         *    $.fn.dataTable.ext.features.push( {
13974.
         *      "fnInit": function( oSettings ) {
13975.
         *        return new TableTools( { "oDTSettings": oSettings } );
13976.
         *      },
13977.
         *      "cFeature": "T"
13978.
         *    } );
13979.
         */
13980.
        feature: [],
13981.
    
13982.
    
13983.
        /**
13984.
         * Row searching.
13985.
         * 
13986.
         * This method of searching is complimentary to the default type based
13987.
         * searching, and a lot more comprehensive as it allows you complete control
13988.
         * over the searching logic. Each element in this array is a function
13989.
         * (parameters described below) that is called for every row in the table,
13990.
         * and your logic decides if it should be included in the searching data set
13991.
         * or not.
13992.
         *
13993.
         * Searching functions have the following input parameters:
13994.
         *
13995.
         * 1. `{object}` DataTables settings object: see
13996.
         *    {@link DataTable.models.oSettings}
13997.
         * 2. `{array|object}` Data for the row to be processed (same as the
13998.
         *    original format that was passed in as the data source, or an array
13999.
         *    from a DOM data source
14000.
         * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
14001.
         *    can be useful to retrieve the `TR` element if you need DOM interaction.
14002.
         *
14003.
         * And the following return is expected:
14004.
         *
14005.
         * * {boolean} Include the row in the searched result set (true) or not
14006.
         *   (false)
14007.
         *
14008.
         * Note that as with the main search ability in DataTables, technically this
14009.
         * is "filtering", since it is subtractive. However, for consistency in
14010.
         * naming we call it searching here.
14011.
         *
14012.
         *  @type array
14013.
         *  @default []
14014.
         *
14015.
         *  @example
14016.
         *    // The following example shows custom search being applied to the
14017.
         *    // fourth column (i.e. the data[3] index) based on two input values
14018.
         *    // from the end-user, matching the data in a certain range.
14019.
         *    $.fn.dataTable.ext.search.push(
14020.
         *      function( settings, data, dataIndex ) {
14021.
         *        var min = document.getElementById('min').value * 1;
14022.
         *        var max = document.getElementById('max').value * 1;
14023.
         *        var version = data[3] == "-" ? 0 : data[3]*1;
14024.
         *
14025.
         *        if ( min == "" && max == "" ) {
14026.
         *          return true;
14027.
         *        }
14028.
         *        else if ( min == "" && version < max ) {
14029.
         *          return true;
14030.
         *        }
14031.
         *        else if ( min < version && "" == max ) {
14032.
         *          return true;
14033.
         *        }
14034.
         *        else if ( min < version && version < max ) {
14035.
         *          return true;
14036.
         *        }
14037.
         *        return false;
14038.
         *      }
14039.
         *    );
14040.
         */
14041.
        search: [],
14042.
    
14043.
    
14044.
        /**
14045.
         * Selector extensions
14046.
         *
14047.
         * The `selector` option can be used to extend the options available for the
14048.
         * selector modifier options (`selector-modifier` object data type) that
14049.
         * each of the three built in selector types offer (row, column and cell +
14050.
         * their plural counterparts). For example the Select extension uses this
14051.
         * mechanism to provide an option to select only rows, columns and cells
14052.
         * that have been marked as selected by the end user (`{selected: true}`),
14053.
         * which can be used in conjunction with the existing built in selector
14054.
         * options.
14055.
         *
14056.
         * Each property is an array to which functions can be pushed. The functions
14057.
         * take three attributes:
14058.
         *
14059.
         * * Settings object for the host table
14060.
         * * Options object (`selector-modifier` object type)
14061.
         * * Array of selected item indexes
14062.
         *
14063.
         * The return is an array of the resulting item indexes after the custom
14064.
         * selector has been applied.
14065.
         *
14066.
         *  @type object
14067.
         */
14068.
        selector: {
14069.
            cell: [],
14070.
            column: [],
14071.
            row: []
14072.
        },
14073.
    
14074.
    
14075.
        /**
14076.
         * Internal functions, exposed for used in plug-ins.
14077.
         * 
14078.
         * Please note that you should not need to use the internal methods for
14079.
         * anything other than a plug-in (and even then, try to avoid if possible).
14080.
         * The internal function may change between releases.
14081.
         *
14082.
         *  @type object
14083.
         *  @default {}
14084.
         */
14085.
        internal: {},
14086.
    
14087.
    
14088.
        /**
14089.
         * Legacy configuration options. Enable and disable legacy options that
14090.
         * are available in DataTables.
14091.
         *
14092.
         *  @type object
14093.
         */
14094.
        legacy: {
14095.
            /**
14096.
             * Enable / disable DataTables 1.9 compatible server-side processing
14097.
             * requests
14098.
             *
14099.
             *  @type boolean
14100.
             *  @default null
14101.
             */
14102.
            ajax: null
14103.
        },
14104.
    
14105.
    
14106.
        /**
14107.
         * Pagination plug-in methods.
14108.
         * 
14109.
         * Each entry in this object is a function and defines which buttons should
14110.
         * be shown by the pagination rendering method that is used for the table:
14111.
         * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
14112.
         * buttons are displayed in the document, while the functions here tell it
14113.
         * what buttons to display. This is done by returning an array of button
14114.
         * descriptions (what each button will do).
14115.
         *
14116.
         * Pagination types (the four built in options and any additional plug-in
14117.
         * options defined here) can be used through the `paginationType`
14118.
         * initialisation parameter.
14119.
         *
14120.
         * The functions defined take two parameters:
14121.
         *
14122.
         * 1. `{int} page` The current page index
14123.
         * 2. `{int} pages` The number of pages in the table
14124.
         *
14125.
         * Each function is expected to return an array where each element of the
14126.
         * array can be one of:
14127.
         *
14128.
         * * `first` - Jump to first page when activated
14129.
         * * `last` - Jump to last page when activated
14130.
         * * `previous` - Show previous page when activated
14131.
         * * `next` - Show next page when activated
14132.
         * * `{int}` - Show page of the index given
14133.
         * * `{array}` - A nested array containing the above elements to add a
14134.
         *   containing 'DIV' element (might be useful for styling).
14135.
         *
14136.
         * Note that DataTables v1.9- used this object slightly differently whereby
14137.
         * an object with two functions would be defined for each plug-in. That
14138.
         * ability is still supported by DataTables 1.10+ to provide backwards
14139.
         * compatibility, but this option of use is now decremented and no longer
14140.
         * documented in DataTables 1.10+.
14141.
         *
14142.
         *  @type object
14143.
         *  @default {}
14144.
         *
14145.
         *  @example
14146.
         *    // Show previous, next and current page buttons only
14147.
         *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
14148.
         *      return [ 'previous', page, 'next' ];
14149.
         *    };
14150.
         */
14151.
        pager: {},
14152.
    
14153.
    
14154.
        renderer: {
14155.
            pageButton: {},
14156.
            header: {}
14157.
        },
14158.
    
14159.
    
14160.
        /**
14161.
         * Ordering plug-ins - custom data source
14162.
         * 
14163.
         * The extension options for ordering of data available here is complimentary
14164.
         * to the default type based ordering that DataTables typically uses. It
14165.
         * allows much greater control over the the data that is being used to
14166.
         * order a column, but is necessarily therefore more complex.
14167.
         * 
14168.
         * This type of ordering is useful if you want to do ordering based on data
14169.
         * live from the DOM (for example the contents of an 'input' element) rather
14170.
         * than just the static string that DataTables knows of.
14171.
         * 
14172.
         * The way these plug-ins work is that you create an array of the values you
14173.
         * wish to be ordering for the column in question and then return that
14174.
         * array. The data in the array much be in the index order of the rows in
14175.
         * the table (not the currently ordering order!). Which order data gathering
14176.
         * function is run here depends on the `dt-init columns.orderDataType`
14177.
         * parameter that is used for the column (if any).
14178.
         *
14179.
         * The functions defined take two parameters:
14180.
         *
14181.
         * 1. `{object}` DataTables settings object: see
14182.
         *    {@link DataTable.models.oSettings}
14183.
         * 2. `{int}` Target column index
14184.
         *
14185.
         * Each function is expected to return an array:
14186.
         *
14187.
         * * `{array}` Data for the column to be ordering upon
14188.
         *
14189.
         *  @type array
14190.
         *
14191.
         *  @example
14192.
         *    // Ordering using `input` node values
14193.
         *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
14194.
         *    {
14195.
         *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
14196.
         *        return $('input', td).val();
14197.
         *      } );
14198.
         *    }
14199.
         */
14200.
        order: {},
14201.
    
14202.
    
14203.
        /**
14204.
         * Type based plug-ins.
14205.
         *
14206.
         * Each column in DataTables has a type assigned to it, either by automatic
14207.
         * detection or by direct assignment using the `type` option for the column.
14208.
         * The type of a column will effect how it is ordering and search (plug-ins
14209.
         * can also make use of the column type if required).
14210.
         *
14211.
         * @namespace
14212.
         */
14213.
        type: {
14214.
            /**
14215.
             * Type detection functions.
14216.
             *
14217.
             * The functions defined in this object are used to automatically detect
14218.
             * a column's type, making initialisation of DataTables super easy, even
14219.
             * when complex data is in the table.
14220.
             *
14221.
             * The functions defined take two parameters:
14222.
             *
14223.
             *  1. `{*}` Data from the column cell to be analysed
14224.
             *  2. `{settings}` DataTables settings object. This can be used to
14225.
             *     perform context specific type detection - for example detection
14226.
             *     based on language settings such as using a comma for a decimal
14227.
             *     place. Generally speaking the options from the settings will not
14228.
             *     be required
14229.
             *
14230.
             * Each function is expected to return:
14231.
             *
14232.
             * * `{string|null}` Data type detected, or null if unknown (and thus
14233.
             *   pass it on to the other type detection functions.
14234.
             *
14235.
             *  @type array
14236.
             *
14237.
             *  @example
14238.
             *    // Currency type detection plug-in:
14239.
             *    $.fn.dataTable.ext.type.detect.push(
14240.
             *      function ( data, settings ) {
14241.
             *        // Check the numeric part
14242.
             *        if ( ! data.substring(1).match(/[0-9]/) ) {
14243.
             *          return null;
14244.
             *        }
14245.
             *
14246.
             *        // Check prefixed by currency
14247.
             *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
14248.
             *          return 'currency';
14249.
             *        }
14250.
             *        return null;
14251.
             *      }
14252.
             *    );
14253.
             */
14254.
            detect: [],
14255.
    
14256.
    
14257.
            /**
14258.
             * Type based search formatting.
14259.
             *
14260.
             * The type based searching functions can be used to pre-format the
14261.
             * data to be search on. For example, it can be used to strip HTML
14262.
             * tags or to de-format telephone numbers for numeric only searching.
14263.
             *
14264.
             * Note that is a search is not defined for a column of a given type,
14265.
             * no search formatting will be performed.
14266.
             * 
14267.
             * Pre-processing of searching data plug-ins - When you assign the sType
14268.
             * for a column (or have it automatically detected for you by DataTables
14269.
             * or a type detection plug-in), you will typically be using this for
14270.
             * custom sorting, but it can also be used to provide custom searching
14271.
             * by allowing you to pre-processing the data and returning the data in
14272.
             * the format that should be searched upon. This is done by adding
14273.
             * functions this object with a parameter name which matches the sType
14274.
             * for that target column. This is the corollary of <i>afnSortData</i>
14275.
             * for searching data.
14276.
             *
14277.
             * The functions defined take a single parameter:
14278.
             *
14279.
             *  1. `{*}` Data from the column cell to be prepared for searching
14280.
             *
14281.
             * Each function is expected to return:
14282.
             *
14283.
             * * `{string|null}` Formatted string that will be used for the searching.
14284.
             *
14285.
             *  @type object
14286.
             *  @default {}
14287.
             *
14288.
             *  @example
14289.
             *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14290.
             *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14291.
             *    }
14292.
             */
14293.
            search: {},
14294.
    
14295.
    
14296.
            /**
14297.
             * Type based ordering.
14298.
             *
14299.
             * The column type tells DataTables what ordering to apply to the table
14300.
             * when a column is sorted upon. The order for each type that is defined,
14301.
             * is defined by the functions available in this object.
14302.
             *
14303.
             * Each ordering option can be described by three properties added to
14304.
             * this object:
14305.
             *
14306.
             * * `{type}-pre` - Pre-formatting function
14307.
             * * `{type}-asc` - Ascending order function
14308.
             * * `{type}-desc` - Descending order function
14309.
             *
14310.
             * All three can be used together, only `{type}-pre` or only
14311.
             * `{type}-asc` and `{type}-desc` together. It is generally recommended
14312.
             * that only `{type}-pre` is used, as this provides the optimal
14313.
             * implementation in terms of speed, although the others are provided
14314.
             * for compatibility with existing Javascript sort functions.
14315.
             *
14316.
             * `{type}-pre`: Functions defined take a single parameter:
14317.
             *
14318.
             *  1. `{*}` Data from the column cell to be prepared for ordering
14319.
             *
14320.
             * And return:
14321.
             *
14322.
             * * `{*}` Data to be sorted upon
14323.
             *
14324.
             * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14325.
             * functions, taking two parameters:
14326.
             *
14327.
             *  1. `{*}` Data to compare to the second parameter
14328.
             *  2. `{*}` Data to compare to the first parameter
14329.
             *
14330.
             * And returning:
14331.
             *
14332.
             * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14333.
             *   than the second parameter, ===0 if the two parameters are equal and
14334.
             *   >0 if the first parameter should be sorted height than the second
14335.
             *   parameter.
14336.
             * 
14337.
             *  @type object
14338.
             *  @default {}
14339.
             *
14340.
             *  @example
14341.
             *    // Numeric ordering of formatted numbers with a pre-formatter
14342.
             *    $.extend( $.fn.dataTable.ext.type.order, {
14343.
             *      "string-pre": function(x) {
14344.
             *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14345.
             *        return parseFloat( a );
14346.
             *      }
14347.
             *    } );
14348.
             *
14349.
             *  @example
14350.
             *    // Case-sensitive string ordering, with no pre-formatting method
14351.
             *    $.extend( $.fn.dataTable.ext.order, {
14352.
             *      "string-case-asc": function(x,y) {
14353.
             *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14354.
             *      },
14355.
             *      "string-case-desc": function(x,y) {
14356.
             *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14357.
             *      }
14358.
             *    } );
14359.
             */
14360.
            order: {}
14361.
        },
14362.
    
14363.
        /**
14364.
         * Unique DataTables instance counter
14365.
         *
14366.
         * @type int
14367.
         * @private
14368.
         */
14369.
        _unique: 0,
14370.
    
14371.
    
14372.
        //
14373.
        // Depreciated
14374.
        // The following properties are retained for backwards compatiblity only.
14375.
        // The should not be used in new projects and will be removed in a future
14376.
        // version
14377.
        //
14378.
    
14379.
        /**
14380.
         * Version check function.
14381.
         *  @type function
14382.
         *  @depreciated Since 1.10
14383.
         */
14384.
        fnVersionCheck: DataTable.fnVersionCheck,
14385.
    
14386.
    
14387.
        /**
14388.
         * Index for what 'this' index API functions should use
14389.
         *  @type int
14390.
         *  @deprecated Since v1.10
14391.
         */
14392.
        iApiIndex: 0,
14393.
    
14394.
    
14395.
        /**
14396.
         * jQuery UI class container
14397.
         *  @type object
14398.
         *  @deprecated Since v1.10
14399.
         */
14400.
        oJUIClasses: {},
14401.
    
14402.
    
14403.
        /**
14404.
         * Software version
14405.
         *  @type string
14406.
         *  @deprecated Since v1.10
14407.
         */
14408.
        sVersion: DataTable.version
14409.
    };
14410.
    
14411.
    
14412.
    //
14413.
    // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14414.
    //
14415.
    $.extend( _ext, {
14416.
        afnFiltering: _ext.search,
14417.
        aTypes:       _ext.type.detect,
14418.
        ofnSearch:    _ext.type.search,
14419.
        oSort:        _ext.type.order,
14420.
        afnSortData:  _ext.order,
14421.
        aoFeatures:   _ext.feature,
14422.
        oApi:         _ext.internal,
14423.
        oStdClasses:  _ext.classes,
14424.
        oPagination:  _ext.pager
14425.
    } );
14426.
    
14427.
    
14428.
    $.extend( DataTable.ext.classes, {
14429.
        "sTable": "dataTable",
14430.
        "sNoFooter": "no-footer",
14431.
    
14432.
        /* Paging buttons */
14433.
        "sPageButton": "paginate_button",
14434.
        "sPageButtonActive": "current",
14435.
        "sPageButtonDisabled": "disabled",
14436.
    
14437.
        /* Striping classes */
14438.
        "sStripeOdd": "odd",
14439.
        "sStripeEven": "even",
14440.
    
14441.
        /* Empty row */
14442.
        "sRowEmpty": "dataTables_empty",
14443.
    
14444.
        /* Features */
14445.
        "sWrapper": "dataTables_wrapper",
14446.
        "sFilter": "dataTables_filter",
14447.
        "sInfo": "dataTables_info",
14448.
        "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14449.
        "sLength": "dataTables_length",
14450.
        "sProcessing": "dataTables_processing",
14451.
    
14452.
        /* Sorting */
14453.
        "sSortAsc": "sorting_asc",
14454.
        "sSortDesc": "sorting_desc",
14455.
        "sSortable": "sorting", /* Sortable in both directions */
14456.
        "sSortableAsc": "sorting_asc_disabled",
14457.
        "sSortableDesc": "sorting_desc_disabled",
14458.
        "sSortableNone": "sorting_disabled",
14459.
        "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14460.
    
14461.
        /* Filtering */
14462.
        "sFilterInput": "",
14463.
    
14464.
        /* Page length */
14465.
        "sLengthSelect": "",
14466.
    
14467.
        /* Scrolling */
14468.
        "sScrollWrapper": "dataTables_scroll",
14469.
        "sScrollHead": "dataTables_scrollHead",
14470.
        "sScrollHeadInner": "dataTables_scrollHeadInner",
14471.
        "sScrollBody": "dataTables_scrollBody",
14472.
        "sScrollFoot": "dataTables_scrollFoot",
14473.
        "sScrollFootInner": "dataTables_scrollFootInner",
14474.
    
14475.
        /* Misc */
14476.
        "sHeaderTH": "",
14477.
        "sFooterTH": "",
14478.
    
14479.
        // Deprecated
14480.
        "sSortJUIAsc": "",
14481.
        "sSortJUIDesc": "",
14482.
        "sSortJUI": "",
14483.
        "sSortJUIAscAllowed": "",
14484.
        "sSortJUIDescAllowed": "",
14485.
        "sSortJUIWrapper": "",
14486.
        "sSortIcon": "",
14487.
        "sJUIHeader": "",
14488.
        "sJUIFooter": ""
14489.
    } );
14490.
    
14491.
    
14492.
    var extPagination = DataTable.ext.pager;
14493.
    
14494.
    function _numbers ( page, pages ) {
14495.
        var
14496.
            numbers = [],
14497.
            buttons = extPagination.numbers_length,
14498.
            half = Math.floor( buttons / 2 ),
14499.
            i = 1;
14500.
    
14501.
        if ( pages <= buttons ) {
14502.
            numbers = _range( 0, pages );
14503.
        }
14504.
        else if ( page <= half ) {
14505.
            numbers = _range( 0, buttons-2 );
14506.
            numbers.push( 'ellipsis' );
14507.
            numbers.push( pages-1 );
14508.
        }
14509.
        else if ( page >= pages - 1 - half ) {
14510.
            numbers = _range( pages-(buttons-2), pages );
14511.
            numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14512.
            numbers.splice( 0, 0, 0 );
14513.
        }
14514.
        else {
14515.
            numbers = _range( page-half+2, page+half-1 );
14516.
            numbers.push( 'ellipsis' );
14517.
            numbers.push( pages-1 );
14518.
            numbers.splice( 0, 0, 'ellipsis' );
14519.
            numbers.splice( 0, 0, 0 );
14520.
        }
14521.
    
14522.
        numbers.DT_el = 'span';
14523.
        return numbers;
14524.
    }
14525.
    
14526.
    
14527.
    $.extend( extPagination, {
14528.
        simple: function ( page, pages ) {
14529.
            return [ 'previous', 'next' ];
14530.
        },
14531.
    
14532.
        full: function ( page, pages ) {
14533.
            return [  'first', 'previous', 'next', 'last' ];
14534.
        },
14535.
    
14536.
        numbers: function ( page, pages ) {
14537.
            return [ _numbers(page, pages) ];
14538.
        },
14539.
    
14540.
        simple_numbers: function ( page, pages ) {
14541.
            return [ 'previous', _numbers(page, pages), 'next' ];
14542.
        },
14543.
    
14544.
        full_numbers: function ( page, pages ) {
14545.
            return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14546.
        },
14547.
        
14548.
        first_last_numbers: function (page, pages) {
14549.
             return ['first', _numbers(page, pages), 'last'];
14550.
         },
14551.
    
14552.
        // For testing and plug-ins to use
14553.
        _numbers: _numbers,
14554.
    
14555.
        // Number of number buttons (including ellipsis) to show. _Must be odd!_
14556.
        numbers_length: 7
14557.
    } );
14558.
    
14559.
    
14560.
    $.extend( true, DataTable.ext.renderer, {
14561.
        pageButton: {
14562.
            _: function ( settings, host, idx, buttons, page, pages ) {
14563.
                var classes = settings.oClasses;
14564.
                var lang = settings.oLanguage.oPaginate;
14565.
                var aria = settings.oLanguage.oAria.paginate || {};
14566.
                var btnDisplay, btnClass, counter=0;
14567.
    
14568.
                var attach = function( container, buttons ) {
14569.
                    var i, ien, node, button, tabIndex;
14570.
                    var disabledClass = classes.sPageButtonDisabled;
14571.
                    var clickHandler = function ( e ) {
14572.
                        _fnPageChange( settings, e.data.action, true );
14573.
                    };
14574.
    
14575.
                    for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14576.
                        button = buttons[i];
14577.
    
14578.
                        if ( $.isArray( button ) ) {
14579.
                            var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14580.
                                .appendTo( container );
14581.
                            attach( inner, button );
14582.
                        }
14583.
                        else {
14584.
                            btnDisplay = null;
14585.
                            btnClass = button;
14586.
                            tabIndex = settings.iTabIndex;
14587.
    
14588.
                            switch ( button ) {
14589.
                                case 'ellipsis':
14590.
                                    container.append('<span class="ellipsis">&#x2026;</span>');
14591.
                                    break;
14592.
    
14593.
                                case 'first':
14594.
                                    btnDisplay = lang.sFirst;
14595.
    
14596.
                                    if ( page === 0 ) {
14597.
                                        tabIndex = -1;
14598.
                                        btnClass += ' ' + disabledClass;
14599.
                                    }
14600.
                                    break;
14601.
    
14602.
                                case 'previous':
14603.
                                    btnDisplay = lang.sPrevious;
14604.
    
14605.
                                    if ( page === 0 ) {
14606.
                                        tabIndex = -1;
14607.
                                        btnClass += ' ' + disabledClass;
14608.
                                    }
14609.
                                    break;
14610.
    
14611.
                                case 'next':
14612.
                                    btnDisplay = lang.sNext;
14613.
    
14614.
                                    if ( pages === 0 || page === pages-1 ) {
14615.
                                        tabIndex = -1;
14616.
                                        btnClass += ' ' + disabledClass;
14617.
                                    }
14618.
                                    break;
14619.
    
14620.
                                case 'last':
14621.
                                    btnDisplay = lang.sLast;
14622.
    
14623.
                                    if ( page === pages-1 ) {
14624.
                                        tabIndex = -1;
14625.
                                        btnClass += ' ' + disabledClass;
14626.
                                    }
14627.
                                    break;
14628.
    
14629.
                                default:
14630.
                                    btnDisplay = button + 1;
14631.
                                    btnClass = page === button ?
14632.
                                        classes.sPageButtonActive : '';
14633.
                                    break;
14634.
                            }
14635.
    
14636.
                            if ( btnDisplay !== null ) {
14637.
                                node = $('<a>', {
14638.
                                        'class': classes.sPageButton+' '+btnClass,
14639.
                                        'aria-controls': settings.sTableId,
14640.
                                        'aria-label': aria[ button ],
14641.
                                        'data-dt-idx': counter,
14642.
                                        'tabindex': tabIndex,
14643.
                                        'id': idx === 0 && typeof button === 'string' ?
14644.
                                            settings.sTableId +'_'+ button :
14645.
                                            null
14646.
                                    } )
14647.
                                    .html( btnDisplay )
14648.
                                    .appendTo( container );
14649.
    
14650.
                                _fnBindAction(
14651.
                                    node, {action: button}, clickHandler
14652.
                                );
14653.
    
14654.
                                counter++;
14655.
                            }
14656.
                        }
14657.
                    }
14658.
                };
14659.
    
14660.
                // IE9 throws an 'unknown error' if document.activeElement is used
14661.
                // inside an iframe or frame. Try / catch the error. Not good for
14662.
                // accessibility, but neither are frames.
14663.
                var activeEl;
14664.
    
14665.
                try {
14666.
                    // Because this approach is destroying and recreating the paging
14667.
                    // elements, focus is lost on the select button which is bad for
14668.
                    // accessibility. So we want to restore focus once the draw has
14669.
                    // completed
14670.
                    activeEl = $(host).find(document.activeElement).data('dt-idx');
14671.
                }
14672.
                catch (e) {}
14673.
    
14674.
                attach( $(host).empty(), buttons );
14675.
    
14676.
                if ( activeEl !== undefined ) {
14677.
                    $(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
14678.
                }
14679.
            }
14680.
        }
14681.
    } );
14682.
    
14683.
    
14684.
    
14685.
    // Built in type detection. See model.ext.aTypes for information about
14686.
    // what is required from this methods.
14687.
    $.extend( DataTable.ext.type.detect, [
14688.
        // Plain numbers - first since V8 detects some plain numbers as dates
14689.
        // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14690.
        function ( d, settings )
14691.
        {
14692.
            var decimal = settings.oLanguage.sDecimal;
14693.
            return _isNumber( d, decimal ) ? 'num'+decimal : null;
14694.
        },
14695.
    
14696.
        // Dates (only those recognised by the browser's Date.parse)
14697.
        function ( d, settings )
14698.
        {
14699.
            // V8 tries _very_ hard to make a string passed into `Date.parse()`
14700.
            // valid, so we need to use a regex to restrict date formats. Use a
14701.
            // plug-in for anything other than ISO8601 style strings
14702.
            if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
14703.
                return null;
14704.
            }
14705.
            var parsed = Date.parse(d);
14706.
            return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14707.
        },
14708.
    
14709.
        // Formatted numbers
14710.
        function ( d, settings )
14711.
        {
14712.
            var decimal = settings.oLanguage.sDecimal;
14713.
            return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14714.
        },
14715.
    
14716.
        // HTML numeric
14717.
        function ( d, settings )
14718.
        {
14719.
            var decimal = settings.oLanguage.sDecimal;
14720.
            return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14721.
        },
14722.
    
14723.
        // HTML numeric, formatted
14724.
        function ( d, settings )
14725.
        {
14726.
            var decimal = settings.oLanguage.sDecimal;
14727.
            return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14728.
        },
14729.
    
14730.
        // HTML (this is strict checking - there must be html)
14731.
        function ( d, settings )
14732.
        {
14733.
            return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14734.
                'html' : null;
14735.
        }
14736.
    ] );
14737.
    
14738.
    
14739.
    
14740.
    // Filter formatting functions. See model.ext.ofnSearch for information about
14741.
    // what is required from these methods.
14742.
    // 
14743.
    // Note that additional search methods are added for the html numbers and
14744.
    // html formatted numbers by `_addNumericSort()` when we know what the decimal
14745.
    // place is
14746.
    
14747.
    
14748.
    $.extend( DataTable.ext.type.search, {
14749.
        html: function ( data ) {
14750.
            return _empty(data) ?
14751.
                data :
14752.
                typeof data === 'string' ?
14753.
                    data
14754.
                        .replace( _re_new_lines, " " )
14755.
                        .replace( _re_html, "" ) :
14756.
                    '';
14757.
        },
14758.
    
14759.
        string: function ( data ) {
14760.
            return _empty(data) ?
14761.
                data :
14762.
                typeof data === 'string' ?
14763.
                    data.replace( _re_new_lines, " " ) :
14764.
                    data;
14765.
        }
14766.
    } );
14767.
    
14768.
    
14769.
    
14770.
    var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14771.
        if ( d !== 0 && (!d || d === '-') ) {
14772.
            return -Infinity;
14773.
        }
14774.
    
14775.
        // If a decimal place other than `.` is used, it needs to be given to the
14776.
        // function so we can detect it and replace with a `.` which is the only
14777.
        // decimal place Javascript recognises - it is not locale aware.
14778.
        if ( decimalPlace ) {
14779.
            d = _numToDecimal( d, decimalPlace );
14780.
        }
14781.
    
14782.
        if ( d.replace ) {
14783.
            if ( re1 ) {
14784.
                d = d.replace( re1, '' );
14785.
            }
14786.
    
14787.
            if ( re2 ) {
14788.
                d = d.replace( re2, '' );
14789.
            }
14790.
        }
14791.
    
14792.
        return d * 1;
14793.
    };
14794.
    
14795.
    
14796.
    // Add the numeric 'deformatting' functions for sorting and search. This is done
14797.
    // in a function to provide an easy ability for the language options to add
14798.
    // additional methods if a non-period decimal place is used.
14799.
    function _addNumericSort ( decimalPlace ) {
14800.
        $.each(
14801.
            {
14802.
                // Plain numbers
14803.
                "num": function ( d ) {
14804.
                    return __numericReplace( d, decimalPlace );
14805.
                },
14806.
    
14807.
                // Formatted numbers
14808.
                "num-fmt": function ( d ) {
14809.
                    return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14810.
                },
14811.
    
14812.
                // HTML numeric
14813.
                "html-num": function ( d ) {
14814.
                    return __numericReplace( d, decimalPlace, _re_html );
14815.
                },
14816.
    
14817.
                // HTML numeric, formatted
14818.
                "html-num-fmt": function ( d ) {
14819.
                    return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14820.
                }
14821.
            },
14822.
            function ( key, fn ) {
14823.
                // Add the ordering method
14824.
                _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14825.
    
14826.
                // For HTML types add a search formatter that will strip the HTML
14827.
                if ( key.match(/^html\-/) ) {
14828.
                    _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14829.
                }
14830.
            }
14831.
        );
14832.
    }
14833.
    
14834.
    
14835.
    // Default sort methods
14836.
    $.extend( _ext.type.order, {
14837.
        // Dates
14838.
        "date-pre": function ( d ) {
14839.
            var ts = Date.parse( d );
14840.
            return isNaN(ts) ? -Infinity : ts;
14841.
        },
14842.
    
14843.
        // html
14844.
        "html-pre": function ( a ) {
14845.
            return _empty(a) ?
14846.
                '' :
14847.
                a.replace ?
14848.
                    a.replace( /<.*?>/g, "" ).toLowerCase() :
14849.
                    a+'';
14850.
        },
14851.
    
14852.
        // string
14853.
        "string-pre": function ( a ) {
14854.
            // This is a little complex, but faster than always calling toString,
14855.
            // http://jsperf.com/tostring-v-check
14856.
            return _empty(a) ?
14857.
                '' :
14858.
                typeof a === 'string' ?
14859.
                    a.toLowerCase() :
14860.
                    ! a.toString ?
14861.
                        '' :
14862.
                        a.toString();
14863.
        },
14864.
    
14865.
        // string-asc and -desc are retained only for compatibility with the old
14866.
        // sort methods
14867.
        "string-asc": function ( x, y ) {
14868.
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14869.
        },
14870.
    
14871.
        "string-desc": function ( x, y ) {
14872.
            return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14873.
        }
14874.
    } );
14875.
    
14876.
    
14877.
    // Numeric sorting types - order doesn't matter here
14878.
    _addNumericSort( '' );
14879.
    
14880.
    
14881.
    $.extend( true, DataTable.ext.renderer, {
14882.
        header: {
14883.
            _: function ( settings, cell, column, classes ) {
14884.
                // No additional mark-up required
14885.
                // Attach a sort listener to update on sort - note that using the
14886.
                // `DT` namespace will allow the event to be removed automatically
14887.
                // on destroy, while the `dt` namespaced event is the one we are
14888.
                // listening for
14889.
                $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14890.
                    if ( settings !== ctx ) { // need to check this this is the host
14891.
                        return;               // table, not a nested one
14892.
                    }
14893.
    
14894.
                    var colIdx = column.idx;
14895.
    
14896.
                    cell
14897.
                        .removeClass(
14898.
                            column.sSortingClass +' '+
14899.
                            classes.sSortAsc +' '+
14900.
                            classes.sSortDesc
14901.
                        )
14902.
                        .addClass( columns[ colIdx ] == 'asc' ?
14903.
                            classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14904.
                                classes.sSortDesc :
14905.
                                column.sSortingClass
14906.
                        );
14907.
                } );
14908.
            },
14909.
    
14910.
            jqueryui: function ( settings, cell, column, classes ) {
14911.
                $('<div/>')
14912.
                    .addClass( classes.sSortJUIWrapper )
14913.
                    .append( cell.contents() )
14914.
                    .append( $('<span/>')
14915.
                        .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14916.
                    )
14917.
                    .appendTo( cell );
14918.
    
14919.
                // Attach a sort listener to update on sort
14920.
                $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14921.
                    if ( settings !== ctx ) {
14922.
                        return;
14923.
                    }
14924.
    
14925.
                    var colIdx = column.idx;
14926.
    
14927.
                    cell
14928.
                        .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14929.
                        .addClass( columns[ colIdx ] == 'asc' ?
14930.
                            classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14931.
                                classes.sSortDesc :
14932.
                                column.sSortingClass
14933.
                        );
14934.
    
14935.
                    cell
14936.
                        .find( 'span.'+classes.sSortIcon )
14937.
                        .removeClass(
14938.
                            classes.sSortJUIAsc +" "+
14939.
                            classes.sSortJUIDesc +" "+
14940.
                            classes.sSortJUI +" "+
14941.
                            classes.sSortJUIAscAllowed +" "+
14942.
                            classes.sSortJUIDescAllowed
14943.
                        )
14944.
                        .addClass( columns[ colIdx ] == 'asc' ?
14945.
                            classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14946.
                                classes.sSortJUIDesc :
14947.
                                column.sSortingClassJUI
14948.
                        );
14949.
                } );
14950.
            }
14951.
        }
14952.
    } );
14953.
    
14954.
    /*
14955.
     * Public helper functions. These aren't used internally by DataTables, or
14956.
     * called by any of the options passed into DataTables, but they can be used
14957.
     * externally by developers working with DataTables. They are helper functions
14958.
     * to make working with DataTables a little bit easier.
14959.
     */
14960.
    
14961.
    var __htmlEscapeEntities = function ( d ) {
14962.
        return typeof d === 'string' ?
14963.
            d
14964.
                .replace(/&/g, '&amp;')
14965.
                .replace(/</g, '&lt;')
14966.
                .replace(/>/g, '&gt;')
14967.
                .replace(/"/g, '&quot;') :
14968.
            d;
14969.
    };
14970.
    
14971.
    /**
14972.
     * Helpers for `columns.render`.
14973.
     *
14974.
     * The options defined here can be used with the `columns.render` initialisation
14975.
     * option to provide a display renderer. The following functions are defined:
14976.
     *
14977.
     * * `number` - Will format numeric data (defined by `columns.data`) for
14978.
     *   display, retaining the original unformatted data for sorting and filtering.
14979.
     *   It takes 5 parameters:
14980.
     *   * `string` - Thousands grouping separator
14981.
     *   * `string` - Decimal point indicator
14982.
     *   * `integer` - Number of decimal points to show
14983.
     *   * `string` (optional) - Prefix.
14984.
     *   * `string` (optional) - Postfix (/suffix).
14985.
     * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
14986.
     *   parameters.
14987.
     *
14988.
     * @example
14989.
     *   // Column definition using the number renderer
14990.
     *   {
14991.
     *     data: "salary",
14992.
     *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14993.
     *   }
14994.
     *
14995.
     * @namespace
14996.
     */
14997.
    DataTable.render = {
14998.
        number: function ( thousands, decimal, precision, prefix, postfix ) {
14999.
            return {
15000.
                display: function ( d ) {
15001.
                    if ( typeof d !== 'number' && typeof d !== 'string' ) {
15002.
                        return d;
15003.
                    }
15004.
    
15005.
                    var negative = d < 0 ? '-' : '';
15006.
                    var flo = parseFloat( d );
15007.
    
15008.
                    // If NaN then there isn't much formatting that we can do - just
15009.
                    // return immediately, escaping any HTML (this was supposed to
15010.
                    // be a number after all)
15011.
                    if ( isNaN( flo ) ) {
15012.
                        return __htmlEscapeEntities( d );
15013.
                    }
15014.
    
15015.
                    flo = flo.toFixed( precision );
15016.
                    d = Math.abs( flo );
15017.
    
15018.
                    var intPart = parseInt( d, 10 );
15019.
                    var floatPart = precision ?
15020.
                        decimal+(d - intPart).toFixed( precision ).substring( 2 ):
15021.
                        '';
15022.
    
15023.
                    return negative + (prefix||'') +
15024.
                        intPart.toString().replace(
15025.
                            /\B(?=(\d{3})+(?!\d))/g, thousands
15026.
                        ) +
15027.
                        floatPart +
15028.
                        (postfix||'');
15029.
                }
15030.
            };
15031.
        },
15032.
    
15033.
        text: function () {
15034.
            return {
15035.
                display: __htmlEscapeEntities,
15036.
                filter: __htmlEscapeEntities
15037.
            };
15038.
        }
15039.
    };
15040.
    
15041.
    
15042.
    /*
15043.
     * This is really a good bit rubbish this method of exposing the internal methods
15044.
     * publicly... - To be fixed in 2.0 using methods on the prototype
15045.
     */
15046.
    
15047.
    
15048.
    /**
15049.
     * Create a wrapper function for exporting an internal functions to an external API.
15050.
     *  @param {string} fn API function name
15051.
     *  @returns {function} wrapped function
15052.
     *  @memberof DataTable#internal
15053.
     */
15054.
    function _fnExternApiFunc (fn)
15055.
    {
15056.
        return function() {
15057.
            var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
15058.
                Array.prototype.slice.call(arguments)
15059.
            );
15060.
            return DataTable.ext.internal[fn].apply( this, args );
15061.
        };
15062.
    }
15063.
    
15064.
    
15065.
    /**
15066.
     * Reference to internal functions for use by plug-in developers. Note that
15067.
     * these methods are references to internal functions and are considered to be
15068.
     * private. If you use these methods, be aware that they are liable to change
15069.
     * between versions.
15070.
     *  @namespace
15071.
     */
15072.
    $.extend( DataTable.ext.internal, {
15073.
        _fnExternApiFunc: _fnExternApiFunc,
15074.
        _fnBuildAjax: _fnBuildAjax,
15075.
        _fnAjaxUpdate: _fnAjaxUpdate,
15076.
        _fnAjaxParameters: _fnAjaxParameters,
15077.
        _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
15078.
        _fnAjaxDataSrc: _fnAjaxDataSrc,
15079.
        _fnAddColumn: _fnAddColumn,
15080.
        _fnColumnOptions: _fnColumnOptions,
15081.
        _fnAdjustColumnSizing: _fnAdjustColumnSizing,
15082.
        _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
15083.
        _fnColumnIndexToVisible: _fnColumnIndexToVisible,
15084.
        _fnVisbleColumns: _fnVisbleColumns,
15085.
        _fnGetColumns: _fnGetColumns,
15086.
        _fnColumnTypes: _fnColumnTypes,
15087.
        _fnApplyColumnDefs: _fnApplyColumnDefs,
15088.
        _fnHungarianMap: _fnHungarianMap,
15089.
        _fnCamelToHungarian: _fnCamelToHungarian,
15090.
        _fnLanguageCompat: _fnLanguageCompat,
15091.
        _fnBrowserDetect: _fnBrowserDetect,
15092.
        _fnAddData: _fnAddData,
15093.
        _fnAddTr: _fnAddTr,
15094.
        _fnNodeToDataIndex: _fnNodeToDataIndex,
15095.
        _fnNodeToColumnIndex: _fnNodeToColumnIndex,
15096.
        _fnGetCellData: _fnGetCellData,
15097.
        _fnSetCellData: _fnSetCellData,
15098.
        _fnSplitObjNotation: _fnSplitObjNotation,
15099.
        _fnGetObjectDataFn: _fnGetObjectDataFn,
15100.
        _fnSetObjectDataFn: _fnSetObjectDataFn,
15101.
        _fnGetDataMaster: _fnGetDataMaster,
15102.
        _fnClearTable: _fnClearTable,
15103.
        _fnDeleteIndex: _fnDeleteIndex,
15104.
        _fnInvalidate: _fnInvalidate,
15105.
        _fnGetRowElements: _fnGetRowElements,
15106.
        _fnCreateTr: _fnCreateTr,
15107.
        _fnBuildHead: _fnBuildHead,
15108.
        _fnDrawHead: _fnDrawHead,
15109.
        _fnDraw: _fnDraw,
15110.
        _fnReDraw: _fnReDraw,
15111.
        _fnAddOptionsHtml: _fnAddOptionsHtml,
15112.
        _fnDetectHeader: _fnDetectHeader,
15113.
        _fnGetUniqueThs: _fnGetUniqueThs,
15114.
        _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
15115.
        _fnFilterComplete: _fnFilterComplete,
15116.
        _fnFilterCustom: _fnFilterCustom,
15117.
        _fnFilterColumn: _fnFilterColumn,
15118.
        _fnFilter: _fnFilter,
15119.
        _fnFilterCreateSearch: _fnFilterCreateSearch,
15120.
        _fnEscapeRegex: _fnEscapeRegex,
15121.
        _fnFilterData: _fnFilterData,
15122.
        _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
15123.
        _fnUpdateInfo: _fnUpdateInfo,
15124.
        _fnInfoMacros: _fnInfoMacros,
15125.
        _fnInitialise: _fnInitialise,
15126.
        _fnInitComplete: _fnInitComplete,
15127.
        _fnLengthChange: _fnLengthChange,
15128.
        _fnFeatureHtmlLength: _fnFeatureHtmlLength,
15129.
        _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
15130.
        _fnPageChange: _fnPageChange,
15131.
        _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
15132.
        _fnProcessingDisplay: _fnProcessingDisplay,
15133.
        _fnFeatureHtmlTable: _fnFeatureHtmlTable,
15134.
        _fnScrollDraw: _fnScrollDraw,
15135.
        _fnApplyToChildren: _fnApplyToChildren,
15136.
        _fnCalculateColumnWidths: _fnCalculateColumnWidths,
15137.
        _fnThrottle: _fnThrottle,
15138.
        _fnConvertToWidth: _fnConvertToWidth,
15139.
        _fnGetWidestNode: _fnGetWidestNode,
15140.
        _fnGetMaxLenString: _fnGetMaxLenString,
15141.
        _fnStringToCss: _fnStringToCss,
15142.
        _fnSortFlatten: _fnSortFlatten,
15143.
        _fnSort: _fnSort,
15144.
        _fnSortAria: _fnSortAria,
15145.
        _fnSortListener: _fnSortListener,
15146.
        _fnSortAttachListener: _fnSortAttachListener,
15147.
        _fnSortingClasses: _fnSortingClasses,
15148.
        _fnSortData: _fnSortData,
15149.
        _fnSaveState: _fnSaveState,
15150.
        _fnLoadState: _fnLoadState,
15151.
        _fnSettingsFromNode: _fnSettingsFromNode,
15152.
        _fnLog: _fnLog,
15153.
        _fnMap: _fnMap,
15154.
        _fnBindAction: _fnBindAction,
15155.
        _fnCallbackReg: _fnCallbackReg,
15156.
        _fnCallbackFire: _fnCallbackFire,
15157.
        _fnLengthOverflow: _fnLengthOverflow,
15158.
        _fnRenderer: _fnRenderer,
15159.
        _fnDataSource: _fnDataSource,
15160.
        _fnRowAttributes: _fnRowAttributes,
15161.
        _fnExtend: _fnExtend,
15162.
        _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
15163.
                                        // in 1.10, so this dead-end function is
15164.
                                        // added to prevent errors
15165.
    } );
15166.
    
15167.
 
15168.
    // jQuery access
15169.
    $.fn.dataTable = DataTable;
15170.
 
15171.
    // Provide access to the host jQuery object (circular reference)
15172.
    DataTable.$ = $;
15173.
 
15174.
    // Legacy aliases
15175.
    $.fn.dataTableSettings = DataTable.settings;
15176.
    $.fn.dataTableExt = DataTable.ext;
15177.
 
15178.
    // With a capital `D` we return a DataTables API instance rather than a
15179.
    // jQuery object
15180.
    $.fn.DataTable = function ( opts ) {
15181.
        return $(this).dataTable( opts ).api();
15182.
    };
15183.
 
15184.
    // All properties that are available to $.fn.dataTable should also be
15185.
    // available on $.fn.DataTable
15186.
    $.each( DataTable, function ( prop, val ) {
15187.
        $.fn.DataTable[ prop ] = val;
15188.
    } );
15189.
 
15190.
 
15191.
    // Information about events fired by DataTables - for documentation.
15192.
    /**
15193.
     * Draw event, fired whenever the table is redrawn on the page, at the same
15194.
     * point as fnDrawCallback. This may be useful for binding events or
15195.
     * performing calculations when the table is altered at all.
15196.
     *  @name DataTable#draw.dt
15197.
     *  @event
15198.
     *  @param {event} e jQuery event object
15199.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15200.
     */
15201.
 
15202.
    /**
15203.
     * Search event, fired when the searching applied to the table (using the
15204.
     * built-in global search, or column filters) is altered.
15205.
     *  @name DataTable#search.dt
15206.
     *  @event
15207.
     *  @param {event} e jQuery event object
15208.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15209.
     */
15210.
 
15211.
    /**
15212.
     * Page change event, fired when the paging of the table is altered.
15213.
     *  @name DataTable#page.dt
15214.
     *  @event
15215.
     *  @param {event} e jQuery event object
15216.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15217.
     */
15218.
 
15219.
    /**
15220.
     * Order event, fired when the ordering applied to the table is altered.
15221.
     *  @name DataTable#order.dt
15222.
     *  @event
15223.
     *  @param {event} e jQuery event object
15224.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15225.
     */
15226.
 
15227.
    /**
15228.
     * DataTables initialisation complete event, fired when the table is fully
15229.
     * drawn, including Ajax data loaded, if Ajax data is required.
15230.
     *  @name DataTable#init.dt
15231.
     *  @event
15232.
     *  @param {event} e jQuery event object
15233.
     *  @param {object} oSettings DataTables settings object
15234.
     *  @param {object} json The JSON object request from the server - only
15235.
     *    present if client-side Ajax sourced data is used</li></ol>
15236.
     */
15237.
 
15238.
    /**
15239.
     * State save event, fired when the table has changed state a new state save
15240.
     * is required. This event allows modification of the state saving object
15241.
     * prior to actually doing the save, including addition or other state
15242.
     * properties (for plug-ins) or modification of a DataTables core property.
15243.
     *  @name DataTable#stateSaveParams.dt
15244.
     *  @event
15245.
     *  @param {event} e jQuery event object
15246.
     *  @param {object} oSettings DataTables settings object
15247.
     *  @param {object} json The state information to be saved
15248.
     */
15249.
 
15250.
    /**
15251.
     * State load event, fired when the table is loading state from the stored
15252.
     * data, but prior to the settings object being modified by the saved state
15253.
     * - allowing modification of the saved state is required or loading of
15254.
     * state for a plug-in.
15255.
     *  @name DataTable#stateLoadParams.dt
15256.
     *  @event
15257.
     *  @param {event} e jQuery event object
15258.
     *  @param {object} oSettings DataTables settings object
15259.
     *  @param {object} json The saved state information
15260.
     */
15261.
 
15262.
    /**
15263.
     * State loaded event, fired when state has been loaded from stored data and
15264.
     * the settings object has been modified by the loaded data.
15265.
     *  @name DataTable#stateLoaded.dt
15266.
     *  @event
15267.
     *  @param {event} e jQuery event object
15268.
     *  @param {object} oSettings DataTables settings object
15269.
     *  @param {object} json The saved state information
15270.
     */
15271.
 
15272.
    /**
15273.
     * Processing event, fired when DataTables is doing some kind of processing
15274.
     * (be it, order, search or anything else). It can be used to indicate to
15275.
     * the end user that there is something happening, or that something has
15276.
     * finished.
15277.
     *  @name DataTable#processing.dt
15278.
     *  @event
15279.
     *  @param {event} e jQuery event object
15280.
     *  @param {object} oSettings DataTables settings object
15281.
     *  @param {boolean} bShow Flag for if DataTables is doing processing or not
15282.
     */
15283.
 
15284.
    /**
15285.
     * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15286.
     * request to made to the server for new data. This event is called before
15287.
     * DataTables processed the returned data, so it can also be used to pre-
15288.
     * process the data returned from the server, if needed.
15289.
     *
15290.
     * Note that this trigger is called in `fnServerData`, if you override
15291.
     * `fnServerData` and which to use this event, you need to trigger it in you
15292.
     * success function.
15293.
     *  @name DataTable#xhr.dt
15294.
     *  @event
15295.
     *  @param {event} e jQuery event object
15296.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15297.
     *  @param {object} json JSON returned from the server
15298.
     *
15299.
     *  @example
15300.
     *     // Use a custom property returned from the server in another DOM element
15301.
     *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15302.
     *       $('#status').html( json.status );
15303.
     *     } );
15304.
     *
15305.
     *  @example
15306.
     *     // Pre-process the data returned from the server
15307.
     *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15308.
     *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15309.
     *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15310.
     *       }
15311.
     *       // Note no return - manipulate the data directly in the JSON object.
15312.
     *     } );
15313.
     */
15314.
 
15315.
    /**
15316.
     * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15317.
     * or passing the bDestroy:true parameter in the initialisation object. This
15318.
     * can be used to remove bound events, added DOM nodes, etc.
15319.
     *  @name DataTable#destroy.dt
15320.
     *  @event
15321.
     *  @param {event} e jQuery event object
15322.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15323.
     */
15324.
 
15325.
    /**
15326.
     * Page length change event, fired when number of records to show on each
15327.
     * page (the length) is changed.
15328.
     *  @name DataTable#length.dt
15329.
     *  @event
15330.
     *  @param {event} e jQuery event object
15331.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15332.
     *  @param {integer} len New length
15333.
     */
15334.
 
15335.
    /**
15336.
     * Column sizing has changed.
15337.
     *  @name DataTable#column-sizing.dt
15338.
     *  @event
15339.
     *  @param {event} e jQuery event object
15340.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15341.
     */
15342.
 
15343.
    /**
15344.
     * Column visibility has changed.
15345.
     *  @name DataTable#column-visibility.dt
15346.
     *  @event
15347.
     *  @param {event} e jQuery event object
15348.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15349.
     *  @param {int} column Column index
15350.
     *  @param {bool} vis `false` if column now hidden, or `true` if visible
15351.
     */
15352.
 
15353.
    return $.fn.dataTable;
15354.
}));
15355.