projects/genea/out/js/DataTables/datatables.js
1.
/*
2.
 * This combined file was created by the DataTables downloader builder:
3.
 *   https://datatables.net/download
4.
 *
5.
 * To rebuild or modify this file with the latest versions of the included
6.
 * software please visit:
7.
 *   https://datatables.net/download/#dt/dt-1.10.21
8.
 *
9.
 * Included libraries:
10.
 *   DataTables 1.10.21
11.
 */
12.
 
13.
/*! DataTables 1.10.21
14.
 * ©2008-2020 SpryMedia Ltd - datatables.net/license
15.
 */
16.
 
17.
/**
18.
 * @summary     DataTables
19.
 * @description Paginate, search and order HTML tables
20.
 * @version     1.10.21
21.
 * @file        jquery.dataTables.js
22.
 * @author      SpryMedia Ltd
23.
 * @contact     www.datatables.net
24.
 * @copyright   Copyright 2008-2020 SpryMedia Ltd.
25.
 *
26.
 * This source file is free software, available under the following license:
27.
 *   MIT license - http://datatables.net/license
28.
 *
29.
 * This source file is distributed in the hope that it will be useful, but
30.
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31.
 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
32.
 *
33.
 * For details please refer to: http://www.datatables.net
34.
 */
35.
 
36.
/*jslint evil: true, undef: true, browser: true */
37.
/*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*/
38.
 
39.
(function( factory ) {
40.
    "use strict";
41.
 
42.
    if ( typeof define === 'function' && define.amd ) {
43.
        // AMD
44.
        define( ['jquery'], function ( $ ) {
45.
            return factory( $, window, document );
46.
        } );
47.
    }
48.
    else if ( typeof exports === 'object' ) {
49.
        // CommonJS
50.
        module.exports = function (root, $) {
51.
            if ( ! root ) {
52.
                // CommonJS environments without a window global must pass a
53.
                // root. This will give an error otherwise
54.
                root = window;
55.
            }
56.
 
57.
            if ( ! $ ) {
58.
                $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
59.
                    require('jquery') :
60.
                    require('jquery')( root );
61.
            }
62.
 
63.
            return factory( $, root, root.document );
64.
        };
65.
    }
66.
    else {
67.
        // Browser
68.
        factory( jQuery, window, document );
69.
    }
70.
}
71.
(function( $, window, document, undefined ) {
72.
    "use strict";
73.
 
74.
    /**
75.
     * DataTables is a plug-in for the jQuery Javascript library. It is a highly
76.
     * flexible tool, based upon the foundations of progressive enhancement,
77.
     * which will add advanced interaction controls to any HTML table. For a
78.
     * full list of features please refer to
79.
     * [DataTables.net](href="http://datatables.net).
80.
     *
81.
     * Note that the `DataTable` object is not a global variable but is aliased
82.
     * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
83.
     * be  accessed.
84.
     *
85.
     *  @class
86.
     *  @param {object} [init={}] Configuration object for DataTables. Options
87.
     *    are defined by {@link DataTable.defaults}
88.
     *  @requires jQuery 1.7+
89.
     *
90.
     *  @example
91.
     *    // Basic initialisation
92.
     *    $(document).ready( function {
93.
     *      $('#example').dataTable();
94.
     *    } );
95.
     *
96.
     *  @example
97.
     *    // Initialisation with configuration options - in this case, disable
98.
     *    // pagination and sorting.
99.
     *    $(document).ready( function {
100.
     *      $('#example').dataTable( {
101.
     *        "paginate": false,
102.
     *        "sort": false
103.
     *      } );
104.
     *    } );
105.
     */
106.
    var DataTable = function ( options )
107.
    {
108.
        /**
109.
         * Perform a jQuery selector action on the table's TR elements (from the tbody) and
110.
         * return the resulting jQuery object.
111.
         *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
112.
         *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
113.
         *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
114.
         *    criterion ("applied") or all TR elements (i.e. no filter).
115.
         *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
116.
         *    Can be either 'current', whereby the current sorting of the table is used, or
117.
         *    'original' whereby the original order the data was read into the table is used.
118.
         *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
119.
         *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
120.
         *    'current' and filter is 'applied', regardless of what they might be given as.
121.
         *  @returns {object} jQuery object, filtered by the given selector.
122.
         *  @dtopt API
123.
         *  @deprecated Since v1.10
124.
         *
125.
         *  @example
126.
         *    $(document).ready(function() {
127.
         *      var oTable = $('#example').dataTable();
128.
         *
129.
         *      // Highlight every second row
130.
         *      oTable.$('tr:odd').css('backgroundColor', 'blue');
131.
         *    } );
132.
         *
133.
         *  @example
134.
         *    $(document).ready(function() {
135.
         *      var oTable = $('#example').dataTable();
136.
         *
137.
         *      // Filter to rows with 'Webkit' in them, add a background colour and then
138.
         *      // remove the filter, thus highlighting the 'Webkit' rows only.
139.
         *      oTable.fnFilter('Webkit');
140.
         *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
141.
         *      oTable.fnFilter('');
142.
         *    } );
143.
         */
144.
        this.$ = function ( sSelector, oOpts )
145.
        {
146.
            return this.api(true).$( sSelector, oOpts );
147.
        };
148.
        
149.
        
150.
        /**
151.
         * Almost identical to $ in operation, but in this case returns the data for the matched
152.
         * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
153.
         * rather than any descendants, so the data can be obtained for the row/cell. If matching
154.
         * rows are found, the data returned is the original data array/object that was used to
155.
         * create the row (or a generated array if from a DOM source).
156.
         *
157.
         * This method is often useful in-combination with $ where both functions are given the
158.
         * same parameters and the array indexes will match identically.
159.
         *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
160.
         *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
161.
         *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
162.
         *    criterion ("applied") or all elements (i.e. no filter).
163.
         *  @param {string} [oOpts.order=current] Order of the data in the processed array.
164.
         *    Can be either 'current', whereby the current sorting of the table is used, or
165.
         *    'original' whereby the original order the data was read into the table is used.
166.
         *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
167.
         *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
168.
         *    'current' and filter is 'applied', regardless of what they might be given as.
169.
         *  @returns {array} Data for the matched elements. If any elements, as a result of the
170.
         *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
171.
         *    entry in the array.
172.
         *  @dtopt API
173.
         *  @deprecated Since v1.10
174.
         *
175.
         *  @example
176.
         *    $(document).ready(function() {
177.
         *      var oTable = $('#example').dataTable();
178.
         *
179.
         *      // Get the data from the first row in the table
180.
         *      var data = oTable._('tr:first');
181.
         *
182.
         *      // Do something useful with the data
183.
         *      alert( "First cell is: "+data[0] );
184.
         *    } );
185.
         *
186.
         *  @example
187.
         *    $(document).ready(function() {
188.
         *      var oTable = $('#example').dataTable();
189.
         *
190.
         *      // Filter to 'Webkit' and get all data for
191.
         *      oTable.fnFilter('Webkit');
192.
         *      var data = oTable._('tr', {"search": "applied"});
193.
         *
194.
         *      // Do something with the data
195.
         *      alert( data.length+" rows matched the search" );
196.
         *    } );
197.
         */
198.
        this._ = function ( sSelector, oOpts )
199.
        {
200.
            return this.api(true).rows( sSelector, oOpts ).data();
201.
        };
202.
        
203.
        
204.
        /**
205.
         * Create a DataTables Api instance, with the currently selected tables for
206.
         * the Api's context.
207.
         * @param {boolean} [traditional=false] Set the API instance's context to be
208.
         *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
209.
         *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
210.
         *   or if all tables captured in the jQuery object should be used.
211.
         * @return {DataTables.Api}
212.
         */
213.
        this.api = function ( traditional )
214.
        {
215.
            return traditional ?
216.
                new _Api(
217.
                    _fnSettingsFromNode( this[ _ext.iApiIndex ] )
218.
                ) :
219.
                new _Api( this );
220.
        };
221.
        
222.
        
223.
        /**
224.
         * Add a single new row or multiple rows of data to the table. Please note
225.
         * that this is suitable for client-side processing only - if you are using
226.
         * server-side processing (i.e. "bServerSide": true), then to add data, you
227.
         * must add it to the data source, i.e. the server-side, through an Ajax call.
228.
         *  @param {array|object} data The data to be added to the table. This can be:
229.
         *    <ul>
230.
         *      <li>1D array of data - add a single row with the data provided</li>
231.
         *      <li>2D array of arrays - add multiple rows in a single call</li>
232.
         *      <li>object - data object when using <i>mData</i></li>
233.
         *      <li>array of objects - multiple data objects when using <i>mData</i></li>
234.
         *    </ul>
235.
         *  @param {bool} [redraw=true] redraw the table or not
236.
         *  @returns {array} An array of integers, representing the list of indexes in
237.
         *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
238.
         *    the table.
239.
         *  @dtopt API
240.
         *  @deprecated Since v1.10
241.
         *
242.
         *  @example
243.
         *    // Global var for counter
244.
         *    var giCount = 2;
245.
         *
246.
         *    $(document).ready(function() {
247.
         *      $('#example').dataTable();
248.
         *    } );
249.
         *
250.
         *    function fnClickAddRow() {
251.
         *      $('#example').dataTable().fnAddData( [
252.
         *        giCount+".1",
253.
         *        giCount+".2",
254.
         *        giCount+".3",
255.
         *        giCount+".4" ]
256.
         *      );
257.
         *
258.
         *      giCount++;
259.
         *    }
260.
         */
261.
        this.fnAddData = function( data, redraw )
262.
        {
263.
            var api = this.api( true );
264.
        
265.
            /* Check if we want to add multiple rows or not */
266.
            var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
267.
                api.rows.add( data ) :
268.
                api.row.add( data );
269.
        
270.
            if ( redraw === undefined || redraw ) {
271.
                api.draw();
272.
            }
273.
        
274.
            return rows.flatten().toArray();
275.
        };
276.
        
277.
        
278.
        /**
279.
         * This function will make DataTables recalculate the column sizes, based on the data
280.
         * contained in the table and the sizes applied to the columns (in the DOM, CSS or
281.
         * through the sWidth parameter). This can be useful when the width of the table's
282.
         * parent element changes (for example a window resize).
283.
         *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
284.
         *  @dtopt API
285.
         *  @deprecated Since v1.10
286.
         *
287.
         *  @example
288.
         *    $(document).ready(function() {
289.
         *      var oTable = $('#example').dataTable( {
290.
         *        "sScrollY": "200px",
291.
         *        "bPaginate": false
292.
         *      } );
293.
         *
294.
         *      $(window).on('resize', function () {
295.
         *        oTable.fnAdjustColumnSizing();
296.
         *      } );
297.
         *    } );
298.
         */
299.
        this.fnAdjustColumnSizing = function ( bRedraw )
300.
        {
301.
            var api = this.api( true ).columns.adjust();
302.
            var settings = api.settings()[0];
303.
            var scroll = settings.oScroll;
304.
        
305.
            if ( bRedraw === undefined || bRedraw ) {
306.
                api.draw( false );
307.
            }
308.
            else if ( scroll.sX !== "" || scroll.sY !== "" ) {
309.
                /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
310.
                _fnScrollDraw( settings );
311.
            }
312.
        };
313.
        
314.
        
315.
        /**
316.
         * Quickly and simply clear a table
317.
         *  @param {bool} [bRedraw=true] redraw the table or not
318.
         *  @dtopt API
319.
         *  @deprecated Since v1.10
320.
         *
321.
         *  @example
322.
         *    $(document).ready(function() {
323.
         *      var oTable = $('#example').dataTable();
324.
         *
325.
         *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
326.
         *      oTable.fnClearTable();
327.
         *    } );
328.
         */
329.
        this.fnClearTable = function( bRedraw )
330.
        {
331.
            var api = this.api( true ).clear();
332.
        
333.
            if ( bRedraw === undefined || bRedraw ) {
334.
                api.draw();
335.
            }
336.
        };
337.
        
338.
        
339.
        /**
340.
         * The exact opposite of 'opening' a row, this function will close any rows which
341.
         * are currently 'open'.
342.
         *  @param {node} nTr the table row to 'close'
343.
         *  @returns {int} 0 on success, or 1 if failed (can't find the row)
344.
         *  @dtopt API
345.
         *  @deprecated Since v1.10
346.
         *
347.
         *  @example
348.
         *    $(document).ready(function() {
349.
         *      var oTable;
350.
         *
351.
         *      // 'open' an information row when a row is clicked on
352.
         *      $('#example tbody tr').click( function () {
353.
         *        if ( oTable.fnIsOpen(this) ) {
354.
         *          oTable.fnClose( this );
355.
         *        } else {
356.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
357.
         *        }
358.
         *      } );
359.
         *
360.
         *      oTable = $('#example').dataTable();
361.
         *    } );
362.
         */
363.
        this.fnClose = function( nTr )
364.
        {
365.
            this.api( true ).row( nTr ).child.hide();
366.
        };
367.
        
368.
        
369.
        /**
370.
         * Remove a row for the table
371.
         *  @param {mixed} target The index of the row from aoData to be deleted, or
372.
         *    the TR element you want to delete
373.
         *  @param {function|null} [callBack] Callback function
374.
         *  @param {bool} [redraw=true] Redraw the table or not
375.
         *  @returns {array} The row that was deleted
376.
         *  @dtopt API
377.
         *  @deprecated Since v1.10
378.
         *
379.
         *  @example
380.
         *    $(document).ready(function() {
381.
         *      var oTable = $('#example').dataTable();
382.
         *
383.
         *      // Immediately remove the first row
384.
         *      oTable.fnDeleteRow( 0 );
385.
         *    } );
386.
         */
387.
        this.fnDeleteRow = function( target, callback, redraw )
388.
        {
389.
            var api = this.api( true );
390.
            var rows = api.rows( target );
391.
            var settings = rows.settings()[0];
392.
            var data = settings.aoData[ rows[0][0] ];
393.
        
394.
            rows.remove();
395.
        
396.
            if ( callback ) {
397.
                callback.call( this, settings, data );
398.
            }
399.
        
400.
            if ( redraw === undefined || redraw ) {
401.
                api.draw();
402.
            }
403.
        
404.
            return data;
405.
        };
406.
        
407.
        
408.
        /**
409.
         * Restore the table to it's original state in the DOM by removing all of DataTables
410.
         * enhancements, alterations to the DOM structure of the table and event listeners.
411.
         *  @param {boolean} [remove=false] Completely remove the table from the DOM
412.
         *  @dtopt API
413.
         *  @deprecated Since v1.10
414.
         *
415.
         *  @example
416.
         *    $(document).ready(function() {
417.
         *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
418.
         *      var oTable = $('#example').dataTable();
419.
         *      oTable.fnDestroy();
420.
         *    } );
421.
         */
422.
        this.fnDestroy = function ( remove )
423.
        {
424.
            this.api( true ).destroy( remove );
425.
        };
426.
        
427.
        
428.
        /**
429.
         * Redraw the table
430.
         *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
431.
         *  @dtopt API
432.
         *  @deprecated Since v1.10
433.
         *
434.
         *  @example
435.
         *    $(document).ready(function() {
436.
         *      var oTable = $('#example').dataTable();
437.
         *
438.
         *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
439.
         *      oTable.fnDraw();
440.
         *    } );
441.
         */
442.
        this.fnDraw = function( complete )
443.
        {
444.
            // Note that this isn't an exact match to the old call to _fnDraw - it takes
445.
            // into account the new data, but can hold position.
446.
            this.api( true ).draw( complete );
447.
        };
448.
        
449.
        
450.
        /**
451.
         * Filter the input based on data
452.
         *  @param {string} sInput String to filter the table on
453.
         *  @param {int|null} [iColumn] Column to limit filtering to
454.
         *  @param {bool} [bRegex=false] Treat as regular expression or not
455.
         *  @param {bool} [bSmart=true] Perform smart filtering or not
456.
         *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
457.
         *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
458.
         *  @dtopt API
459.
         *  @deprecated Since v1.10
460.
         *
461.
         *  @example
462.
         *    $(document).ready(function() {
463.
         *      var oTable = $('#example').dataTable();
464.
         *
465.
         *      // Sometime later - filter...
466.
         *      oTable.fnFilter( 'test string' );
467.
         *    } );
468.
         */
469.
        this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
470.
        {
471.
            var api = this.api( true );
472.
        
473.
            if ( iColumn === null || iColumn === undefined ) {
474.
                api.search( sInput, bRegex, bSmart, bCaseInsensitive );
475.
            }
476.
            else {
477.
                api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
478.
            }
479.
        
480.
            api.draw();
481.
        };
482.
        
483.
        
484.
        /**
485.
         * Get the data for the whole table, an individual row or an individual cell based on the
486.
         * provided parameters.
487.
         *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
488.
         *    a TR node then the data source for the whole row will be returned. If given as a
489.
         *    TD/TH cell node then iCol will be automatically calculated and the data for the
490.
         *    cell returned. If given as an integer, then this is treated as the aoData internal
491.
         *    data index for the row (see fnGetPosition) and the data for that row used.
492.
         *  @param {int} [col] Optional column index that you want the data of.
493.
         *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
494.
         *    returned. If mRow is defined, just data for that row, and is iCol is
495.
         *    defined, only data for the designated cell is returned.
496.
         *  @dtopt API
497.
         *  @deprecated Since v1.10
498.
         *
499.
         *  @example
500.
         *    // Row data
501.
         *    $(document).ready(function() {
502.
         *      oTable = $('#example').dataTable();
503.
         *
504.
         *      oTable.$('tr').click( function () {
505.
         *        var data = oTable.fnGetData( this );
506.
         *        // ... do something with the array / object of data for the row
507.
         *      } );
508.
         *    } );
509.
         *
510.
         *  @example
511.
         *    // Individual cell data
512.
         *    $(document).ready(function() {
513.
         *      oTable = $('#example').dataTable();
514.
         *
515.
         *      oTable.$('td').click( function () {
516.
         *        var sData = oTable.fnGetData( this );
517.
         *        alert( 'The cell clicked on had the value of '+sData );
518.
         *      } );
519.
         *    } );
520.
         */
521.
        this.fnGetData = function( src, col )
522.
        {
523.
            var api = this.api( true );
524.
        
525.
            if ( src !== undefined ) {
526.
                var type = src.nodeName ? src.nodeName.toLowerCase() : '';
527.
        
528.
                return col !== undefined || type == 'td' || type == 'th' ?
529.
                    api.cell( src, col ).data() :
530.
                    api.row( src ).data() || null;
531.
            }
532.
        
533.
            return api.data().toArray();
534.
        };
535.
        
536.
        
537.
        /**
538.
         * Get an array of the TR nodes that are used in the table's body. Note that you will
539.
         * typically want to use the '$' API method in preference to this as it is more
540.
         * flexible.
541.
         *  @param {int} [iRow] Optional row index for the TR element you want
542.
         *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
543.
         *    in the table's body, or iRow is defined, just the TR element requested.
544.
         *  @dtopt API
545.
         *  @deprecated Since v1.10
546.
         *
547.
         *  @example
548.
         *    $(document).ready(function() {
549.
         *      var oTable = $('#example').dataTable();
550.
         *
551.
         *      // Get the nodes from the table
552.
         *      var nNodes = oTable.fnGetNodes( );
553.
         *    } );
554.
         */
555.
        this.fnGetNodes = function( iRow )
556.
        {
557.
            var api = this.api( true );
558.
        
559.
            return iRow !== undefined ?
560.
                api.row( iRow ).node() :
561.
                api.rows().nodes().flatten().toArray();
562.
        };
563.
        
564.
        
565.
        /**
566.
         * Get the array indexes of a particular cell from it's DOM element
567.
         * and column index including hidden columns
568.
         *  @param {node} node this can either be a TR, TD or TH in the table's body
569.
         *  @returns {int} If nNode is given as a TR, then a single index is returned, or
570.
         *    if given as a cell, an array of [row index, column index (visible),
571.
         *    column index (all)] is given.
572.
         *  @dtopt API
573.
         *  @deprecated Since v1.10
574.
         *
575.
         *  @example
576.
         *    $(document).ready(function() {
577.
         *      $('#example tbody td').click( function () {
578.
         *        // Get the position of the current data from the node
579.
         *        var aPos = oTable.fnGetPosition( this );
580.
         *
581.
         *        // Get the data array for this row
582.
         *        var aData = oTable.fnGetData( aPos[0] );
583.
         *
584.
         *        // Update the data array and return the value
585.
         *        aData[ aPos[1] ] = 'clicked';
586.
         *        this.innerHTML = 'clicked';
587.
         *      } );
588.
         *
589.
         *      // Init DataTables
590.
         *      oTable = $('#example').dataTable();
591.
         *    } );
592.
         */
593.
        this.fnGetPosition = function( node )
594.
        {
595.
            var api = this.api( true );
596.
            var nodeName = node.nodeName.toUpperCase();
597.
        
598.
            if ( nodeName == 'TR' ) {
599.
                return api.row( node ).index();
600.
            }
601.
            else if ( nodeName == 'TD' || nodeName == 'TH' ) {
602.
                var cell = api.cell( node ).index();
603.
        
604.
                return [
605.
                    cell.row,
606.
                    cell.columnVisible,
607.
                    cell.column
608.
                ];
609.
            }
610.
            return null;
611.
        };
612.
        
613.
        
614.
        /**
615.
         * Check to see if a row is 'open' or not.
616.
         *  @param {node} nTr the table row to check
617.
         *  @returns {boolean} true if the row is currently open, false otherwise
618.
         *  @dtopt API
619.
         *  @deprecated Since v1.10
620.
         *
621.
         *  @example
622.
         *    $(document).ready(function() {
623.
         *      var oTable;
624.
         *
625.
         *      // 'open' an information row when a row is clicked on
626.
         *      $('#example tbody tr').click( function () {
627.
         *        if ( oTable.fnIsOpen(this) ) {
628.
         *          oTable.fnClose( this );
629.
         *        } else {
630.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
631.
         *        }
632.
         *      } );
633.
         *
634.
         *      oTable = $('#example').dataTable();
635.
         *    } );
636.
         */
637.
        this.fnIsOpen = function( nTr )
638.
        {
639.
            return this.api( true ).row( nTr ).child.isShown();
640.
        };
641.
        
642.
        
643.
        /**
644.
         * This function will place a new row directly after a row which is currently
645.
         * on display on the page, with the HTML contents that is passed into the
646.
         * function. This can be used, for example, to ask for confirmation that a
647.
         * particular record should be deleted.
648.
         *  @param {node} nTr The table row to 'open'
649.
         *  @param {string|node|jQuery} mHtml The HTML to put into the row
650.
         *  @param {string} sClass Class to give the new TD cell
651.
         *  @returns {node} The row opened. Note that if the table row passed in as the
652.
         *    first parameter, is not found in the table, this method will silently
653.
         *    return.
654.
         *  @dtopt API
655.
         *  @deprecated Since v1.10
656.
         *
657.
         *  @example
658.
         *    $(document).ready(function() {
659.
         *      var oTable;
660.
         *
661.
         *      // 'open' an information row when a row is clicked on
662.
         *      $('#example tbody tr').click( function () {
663.
         *        if ( oTable.fnIsOpen(this) ) {
664.
         *          oTable.fnClose( this );
665.
         *        } else {
666.
         *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
667.
         *        }
668.
         *      } );
669.
         *
670.
         *      oTable = $('#example').dataTable();
671.
         *    } );
672.
         */
673.
        this.fnOpen = function( nTr, mHtml, sClass )
674.
        {
675.
            return this.api( true )
676.
                .row( nTr )
677.
                .child( mHtml, sClass )
678.
                .show()
679.
                .child()[0];
680.
        };
681.
        
682.
        
683.
        /**
684.
         * Change the pagination - provides the internal logic for pagination in a simple API
685.
         * function. With this function you can have a DataTables table go to the next,
686.
         * previous, first or last pages.
687.
         *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
688.
         *    or page number to jump to (integer), note that page 0 is the first page.
689.
         *  @param {bool} [bRedraw=true] Redraw the table or not
690.
         *  @dtopt API
691.
         *  @deprecated Since v1.10
692.
         *
693.
         *  @example
694.
         *    $(document).ready(function() {
695.
         *      var oTable = $('#example').dataTable();
696.
         *      oTable.fnPageChange( 'next' );
697.
         *    } );
698.
         */
699.
        this.fnPageChange = function ( mAction, bRedraw )
700.
        {
701.
            var api = this.api( true ).page( mAction );
702.
        
703.
            if ( bRedraw === undefined || bRedraw ) {
704.
                api.draw(false);
705.
            }
706.
        };
707.
        
708.
        
709.
        /**
710.
         * Show a particular column
711.
         *  @param {int} iCol The column whose display should be changed
712.
         *  @param {bool} bShow Show (true) or hide (false) the column
713.
         *  @param {bool} [bRedraw=true] Redraw the table or not
714.
         *  @dtopt API
715.
         *  @deprecated Since v1.10
716.
         *
717.
         *  @example
718.
         *    $(document).ready(function() {
719.
         *      var oTable = $('#example').dataTable();
720.
         *
721.
         *      // Hide the second column after initialisation
722.
         *      oTable.fnSetColumnVis( 1, false );
723.
         *    } );
724.
         */
725.
        this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
726.
        {
727.
            var api = this.api( true ).column( iCol ).visible( bShow );
728.
        
729.
            if ( bRedraw === undefined || bRedraw ) {
730.
                api.columns.adjust().draw();
731.
            }
732.
        };
733.
        
734.
        
735.
        /**
736.
         * Get the settings for a particular table for external manipulation
737.
         *  @returns {object} DataTables settings object. See
738.
         *    {@link DataTable.models.oSettings}
739.
         *  @dtopt API
740.
         *  @deprecated Since v1.10
741.
         *
742.
         *  @example
743.
         *    $(document).ready(function() {
744.
         *      var oTable = $('#example').dataTable();
745.
         *      var oSettings = oTable.fnSettings();
746.
         *
747.
         *      // Show an example parameter from the settings
748.
         *      alert( oSettings._iDisplayStart );
749.
         *    } );
750.
         */
751.
        this.fnSettings = function()
752.
        {
753.
            return _fnSettingsFromNode( this[_ext.iApiIndex] );
754.
        };
755.
        
756.
        
757.
        /**
758.
         * Sort the table by a particular column
759.
         *  @param {int} iCol the data index to sort on. Note that this will not match the
760.
         *    'display index' if you have hidden data entries
761.
         *  @dtopt API
762.
         *  @deprecated Since v1.10
763.
         *
764.
         *  @example
765.
         *    $(document).ready(function() {
766.
         *      var oTable = $('#example').dataTable();
767.
         *
768.
         *      // Sort immediately with columns 0 and 1
769.
         *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
770.
         *    } );
771.
         */
772.
        this.fnSort = function( aaSort )
773.
        {
774.
            this.api( true ).order( aaSort ).draw();
775.
        };
776.
        
777.
        
778.
        /**
779.
         * Attach a sort listener to an element for a given column
780.
         *  @param {node} nNode the element to attach the sort listener to
781.
         *  @param {int} iColumn the column that a click on this node will sort on
782.
         *  @param {function} [fnCallback] callback function when sort is run
783.
         *  @dtopt API
784.
         *  @deprecated Since v1.10
785.
         *
786.
         *  @example
787.
         *    $(document).ready(function() {
788.
         *      var oTable = $('#example').dataTable();
789.
         *
790.
         *      // Sort on column 1, when 'sorter' is clicked on
791.
         *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
792.
         *    } );
793.
         */
794.
        this.fnSortListener = function( nNode, iColumn, fnCallback )
795.
        {
796.
            this.api( true ).order.listener( nNode, iColumn, fnCallback );
797.
        };
798.
        
799.
        
800.
        /**
801.
         * Update a table cell or row - this method will accept either a single value to
802.
         * update the cell with, an array of values with one element for each column or
803.
         * an object in the same format as the original data source. The function is
804.
         * self-referencing in order to make the multi column updates easier.
805.
         *  @param {object|array|string} mData Data to update the cell/row with
806.
         *  @param {node|int} mRow TR element you want to update or the aoData index
807.
         *  @param {int} [iColumn] The column to update, give as null or undefined to
808.
         *    update a whole row.
809.
         *  @param {bool} [bRedraw=true] Redraw the table or not
810.
         *  @param {bool} [bAction=true] Perform pre-draw actions or not
811.
         *  @returns {int} 0 on success, 1 on error
812.
         *  @dtopt API
813.
         *  @deprecated Since v1.10
814.
         *
815.
         *  @example
816.
         *    $(document).ready(function() {
817.
         *      var oTable = $('#example').dataTable();
818.
         *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
819.
         *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
820.
         *    } );
821.
         */
822.
        this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
823.
        {
824.
            var api = this.api( true );
825.
        
826.
            if ( iColumn === undefined || iColumn === null ) {
827.
                api.row( mRow ).data( mData );
828.
            }
829.
            else {
830.
                api.cell( mRow, iColumn ).data( mData );
831.
            }
832.
        
833.
            if ( bAction === undefined || bAction ) {
834.
                api.columns.adjust();
835.
            }
836.
        
837.
            if ( bRedraw === undefined || bRedraw ) {
838.
                api.draw();
839.
            }
840.
            return 0;
841.
        };
842.
        
843.
        
844.
        /**
845.
         * Provide a common method for plug-ins to check the version of DataTables being used, in order
846.
         * to ensure compatibility.
847.
         *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
848.
         *    formats "X" and "X.Y" are also acceptable.
849.
         *  @returns {boolean} true if this version of DataTables is greater or equal to the required
850.
         *    version, or false if this version of DataTales is not suitable
851.
         *  @method
852.
         *  @dtopt API
853.
         *  @deprecated Since v1.10
854.
         *
855.
         *  @example
856.
         *    $(document).ready(function() {
857.
         *      var oTable = $('#example').dataTable();
858.
         *      alert( oTable.fnVersionCheck( '1.9.0' ) );
859.
         *    } );
860.
         */
861.
        this.fnVersionCheck = _ext.fnVersionCheck;
862.
        
863.
 
864.
        var _that = this;
865.
        var emptyInit = options === undefined;
866.
        var len = this.length;
867.
 
868.
        if ( emptyInit ) {
869.
            options = {};
870.
        }
871.
 
872.
        this.oApi = this.internal = _ext.internal;
873.
 
874.
        // Extend with old style plug-in API methods
875.
        for ( var fn in DataTable.ext.internal ) {
876.
            if ( fn ) {
877.
                this[fn] = _fnExternApiFunc(fn);
878.
            }
879.
        }
880.
 
881.
        this.each(function() {
882.
            // For each initialisation we want to give it a clean initialisation
883.
            // object that can be bashed around
884.
            var o = {};
885.
            var oInit = len > 1 ? // optimisation for single table case
886.
                _fnExtend( o, options, true ) :
887.
                options;
888.
 
889.
            /*global oInit,_that,emptyInit*/
890.
            var i=0, iLen, j, jLen, k, kLen;
891.
            var sId = this.getAttribute( 'id' );
892.
            var bInitHandedOff = false;
893.
            var defaults = DataTable.defaults;
894.
            var $this = $(this);
895.
            
896.
            
897.
            /* Sanity check */
898.
            if ( this.nodeName.toLowerCase() != 'table' )
899.
            {
900.
                _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
901.
                return;
902.
            }
903.
            
904.
            /* Backwards compatibility for the defaults */
905.
            _fnCompatOpts( defaults );
906.
            _fnCompatCols( defaults.column );
907.
            
908.
            /* Convert the camel-case defaults to Hungarian */
909.
            _fnCamelToHungarian( defaults, defaults, true );
910.
            _fnCamelToHungarian( defaults.column, defaults.column, true );
911.
            
912.
            /* Setting up the initialisation object */
913.
            _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );
914.
            
915.
            
916.
            
917.
            /* Check to see if we are re-initialising a table */
918.
            var allSettings = DataTable.settings;
919.
            for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
920.
            {
921.
                var s = allSettings[i];
922.
            
923.
                /* Base check on table node */
924.
                if (
925.
                    s.nTable == this ||
926.
                    (s.nTHead && s.nTHead.parentNode == this) ||
927.
                    (s.nTFoot && s.nTFoot.parentNode == this)
928.
                ) {
929.
                    var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
930.
                    var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
931.
            
932.
                    if ( emptyInit || bRetrieve )
933.
                    {
934.
                        return s.oInstance;
935.
                    }
936.
                    else if ( bDestroy )
937.
                    {
938.
                        s.oInstance.fnDestroy();
939.
                        break;
940.
                    }
941.
                    else
942.
                    {
943.
                        _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
944.
                        return;
945.
                    }
946.
                }
947.
            
948.
                /* If the element we are initialising has the same ID as a table which was previously
949.
                 * initialised, but the table nodes don't match (from before) then we destroy the old
950.
                 * instance by simply deleting it. This is under the assumption that the table has been
951.
                 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
952.
                 */
953.
                if ( s.sTableId == this.id )
954.
                {
955.
                    allSettings.splice( i, 1 );
956.
                    break;
957.
                }
958.
            }
959.
            
960.
            /* Ensure the table has an ID - required for accessibility */
961.
            if ( sId === null || sId === "" )
962.
            {
963.
                sId = "DataTables_Table_"+(DataTable.ext._unique++);
964.
                this.id = sId;
965.
            }
966.
            
967.
            /* Create the settings object for this table and set some of the default parameters */
968.
            var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
969.
                "sDestroyWidth": $this[0].style.width,
970.
                "sInstance":     sId,
971.
                "sTableId":      sId
972.
            } );
973.
            oSettings.nTable = this;
974.
            oSettings.oApi   = _that.internal;
975.
            oSettings.oInit  = oInit;
976.
            
977.
            allSettings.push( oSettings );
978.
            
979.
            // Need to add the instance after the instance after the settings object has been added
980.
            // to the settings array, so we can self reference the table instance if more than one
981.
            oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
982.
            
983.
            // Backwards compatibility, before we apply all the defaults
984.
            _fnCompatOpts( oInit );
985.
            _fnLanguageCompat( oInit.oLanguage );
986.
            
987.
            // If the length menu is given, but the init display length is not, use the length menu
988.
            if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
989.
            {
990.
                oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
991.
                    oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
992.
            }
993.
            
994.
            // Apply the defaults and init options to make a single init object will all
995.
            // options defined from defaults and instance options.
996.
            oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
997.
            
998.
            
999.
            // Map the initialisation options onto the settings object
1000.
            _fnMap( oSettings.oFeatures, oInit, [
1001.
                "bPaginate",
1002.
                "bLengthChange",
1003.
                "bFilter",
1004.
                "bSort",
1005.
                "bSortMulti",
1006.
                "bInfo",
1007.
                "bProcessing",
1008.
                "bAutoWidth",
1009.
                "bSortClasses",
1010.
                "bServerSide",
1011.
                "bDeferRender"
1012.
            ] );
1013.
            _fnMap( oSettings, oInit, [
1014.
                "asStripeClasses",
1015.
                "ajax",
1016.
                "fnServerData",
1017.
                "fnFormatNumber",
1018.
                "sServerMethod",
1019.
                "aaSorting",
1020.
                "aaSortingFixed",
1021.
                "aLengthMenu",
1022.
                "sPaginationType",
1023.
                "sAjaxSource",
1024.
                "sAjaxDataProp",
1025.
                "iStateDuration",
1026.
                "sDom",
1027.
                "bSortCellsTop",
1028.
                "iTabIndex",
1029.
                "fnStateLoadCallback",
1030.
                "fnStateSaveCallback",
1031.
                "renderer",
1032.
                "searchDelay",
1033.
                "rowId",
1034.
                [ "iCookieDuration", "iStateDuration" ], // backwards compat
1035.
                [ "oSearch", "oPreviousSearch" ],
1036.
                [ "aoSearchCols", "aoPreSearchCols" ],
1037.
                [ "iDisplayLength", "_iDisplayLength" ]
1038.
            ] );
1039.
            _fnMap( oSettings.oScroll, oInit, [
1040.
                [ "sScrollX", "sX" ],
1041.
                [ "sScrollXInner", "sXInner" ],
1042.
                [ "sScrollY", "sY" ],
1043.
                [ "bScrollCollapse", "bCollapse" ]
1044.
            ] );
1045.
            _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
1046.
            
1047.
            /* Callback functions which are array driven */
1048.
            _fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
1049.
            _fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
1050.
            _fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
1051.
            _fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
1052.
            _fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
1053.
            _fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
1054.
            _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
1055.
            _fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
1056.
            _fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
1057.
            _fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
1058.
            _fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
1059.
            
1060.
            oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
1061.
            
1062.
            /* Browser support detection */
1063.
            _fnBrowserDetect( oSettings );
1064.
            
1065.
            var oClasses = oSettings.oClasses;
1066.
            
1067.
            $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
1068.
            $this.addClass( oClasses.sTable );
1069.
            
1070.
            
1071.
            if ( oSettings.iInitDisplayStart === undefined )
1072.
            {
1073.
                /* Display start point, taking into account the save saving */
1074.
                oSettings.iInitDisplayStart = oInit.iDisplayStart;
1075.
                oSettings._iDisplayStart = oInit.iDisplayStart;
1076.
            }
1077.
            
1078.
            if ( oInit.iDeferLoading !== null )
1079.
            {
1080.
                oSettings.bDeferLoading = true;
1081.
                var tmp = $.isArray( oInit.iDeferLoading );
1082.
                oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
1083.
                oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
1084.
            }
1085.
            
1086.
            /* Language definitions */
1087.
            var oLanguage = oSettings.oLanguage;
1088.
            $.extend( true, oLanguage, oInit.oLanguage );
1089.
            
1090.
            if ( oLanguage.sUrl )
1091.
            {
1092.
                /* Get the language definitions from a file - because this Ajax call makes the language
1093.
                 * get async to the remainder of this function we use bInitHandedOff to indicate that
1094.
                 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
1095.
                 */
1096.
                $.ajax( {
1097.
                    dataType: 'json',
1098.
                    url: oLanguage.sUrl,
1099.
                    success: function ( json ) {
1100.
                        _fnLanguageCompat( json );
1101.
                        _fnCamelToHungarian( defaults.oLanguage, json );
1102.
                        $.extend( true, oLanguage, json );
1103.
                        _fnInitialise( oSettings );
1104.
                    },
1105.
                    error: function () {
1106.
                        // Error occurred loading language file, continue on as best we can
1107.
                        _fnInitialise( oSettings );
1108.
                    }
1109.
                } );
1110.
                bInitHandedOff = true;
1111.
            }
1112.
            
1113.
            /*
1114.
             * Stripes
1115.
             */
1116.
            if ( oInit.asStripeClasses === null )
1117.
            {
1118.
                oSettings.asStripeClasses =[
1119.
                    oClasses.sStripeOdd,
1120.
                    oClasses.sStripeEven
1121.
                ];
1122.
            }
1123.
            
1124.
            /* Remove row stripe classes if they are already on the table row */
1125.
            var stripeClasses = oSettings.asStripeClasses;
1126.
            var rowOne = $this.children('tbody').find('tr').eq(0);
1127.
            if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
1128.
                return rowOne.hasClass(el);
1129.
            } ) ) !== -1 ) {
1130.
                $('tbody tr', this).removeClass( stripeClasses.join(' ') );
1131.
                oSettings.asDestroyStripes = stripeClasses.slice();
1132.
            }
1133.
            
1134.
            /*
1135.
             * Columns
1136.
             * See if we should load columns automatically or use defined ones
1137.
             */
1138.
            var anThs = [];
1139.
            var aoColumnsInit;
1140.
            var nThead = this.getElementsByTagName('thead');
1141.
            if ( nThead.length !== 0 )
1142.
            {
1143.
                _fnDetectHeader( oSettings.aoHeader, nThead[0] );
1144.
                anThs = _fnGetUniqueThs( oSettings );
1145.
            }
1146.
            
1147.
            /* If not given a column array, generate one with nulls */
1148.
            if ( oInit.aoColumns === null )
1149.
            {
1150.
                aoColumnsInit = [];
1151.
                for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
1152.
                {
1153.
                    aoColumnsInit.push( null );
1154.
                }
1155.
            }
1156.
            else
1157.
            {
1158.
                aoColumnsInit = oInit.aoColumns;
1159.
            }
1160.
            
1161.
            /* Add the columns */
1162.
            for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
1163.
            {
1164.
                _fnAddColumn( oSettings, anThs ? anThs[i] : null );
1165.
            }
1166.
            
1167.
            /* Apply the column definitions */
1168.
            _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
1169.
                _fnColumnOptions( oSettings, iCol, oDef );
1170.
            } );
1171.
            
1172.
            /* HTML5 attribute detection - build an mData object automatically if the
1173.
             * attributes are found
1174.
             */
1175.
            if ( rowOne.length ) {
1176.
                var a = function ( cell, name ) {
1177.
                    return cell.getAttribute( 'data-'+name ) !== null ? name : null;
1178.
                };
1179.
            
1180.
                $( rowOne[0] ).children('th, td').each( function (i, cell) {
1181.
                    var col = oSettings.aoColumns[i];
1182.
            
1183.
                    if ( col.mData === i ) {
1184.
                        var sort = a( cell, 'sort' ) || a( cell, 'order' );
1185.
                        var filter = a( cell, 'filter' ) || a( cell, 'search' );
1186.
            
1187.
                        if ( sort !== null || filter !== null ) {
1188.
                            col.mData = {
1189.
                                _:      i+'.display',
1190.
                                sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
1191.
                                type:   sort !== null   ? i+'.@data-'+sort   : undefined,
1192.
                                filter: filter !== null ? i+'.@data-'+filter : undefined
1193.
                            };
1194.
            
1195.
                            _fnColumnOptions( oSettings, i );
1196.
                        }
1197.
                    }
1198.
                } );
1199.
            }
1200.
            
1201.
            var features = oSettings.oFeatures;
1202.
            var loadedInit = function () {
1203.
                /*
1204.
                 * Sorting
1205.
                 * @todo For modularisation (1.11) this needs to do into a sort start up handler
1206.
                 */
1207.
            
1208.
                // If aaSorting is not defined, then we use the first indicator in asSorting
1209.
                // in case that has been altered, so the default sort reflects that option
1210.
                if ( oInit.aaSorting === undefined ) {
1211.
                    var sorting = oSettings.aaSorting;
1212.
                    for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
1213.
                        sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1214.
                    }
1215.
                }
1216.
            
1217.
                /* Do a first pass on the sorting classes (allows any size changes to be taken into
1218.
                 * account, and also will apply sorting disabled classes if disabled
1219.
                 */
1220.
                _fnSortingClasses( oSettings );
1221.
            
1222.
                if ( features.bSort ) {
1223.
                    _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1224.
                        if ( oSettings.bSorted ) {
1225.
                            var aSort = _fnSortFlatten( oSettings );
1226.
                            var sortedColumns = {};
1227.
            
1228.
                            $.each( aSort, function (i, val) {
1229.
                                sortedColumns[ val.src ] = val.dir;
1230.
                            } );
1231.
            
1232.
                            _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
1233.
                            _fnSortAria( oSettings );
1234.
                        }
1235.
                    } );
1236.
                }
1237.
            
1238.
                _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1239.
                    if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
1240.
                        _fnSortingClasses( oSettings );
1241.
                    }
1242.
                }, 'sc' );
1243.
            
1244.
            
1245.
                /*
1246.
                 * Final init
1247.
                 * Cache the header, body and footer as required, creating them if needed
1248.
                 */
1249.
            
1250.
                // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1251.
                var captions = $this.children('caption').each( function () {
1252.
                    this._captionSide = $(this).css('caption-side');
1253.
                } );
1254.
            
1255.
                var thead = $this.children('thead');
1256.
                if ( thead.length === 0 ) {
1257.
                    thead = $('<thead/>').appendTo($this);
1258.
                }
1259.
                oSettings.nTHead = thead[0];
1260.
            
1261.
                var tbody = $this.children('tbody');
1262.
                if ( tbody.length === 0 ) {
1263.
                    tbody = $('<tbody/>').appendTo($this);
1264.
                }
1265.
                oSettings.nTBody = tbody[0];
1266.
            
1267.
                var tfoot = $this.children('tfoot');
1268.
                if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
1269.
                    // If we are a scrolling table, and no footer has been given, then we need to create
1270.
                    // a tfoot element for the caption element to be appended to
1271.
                    tfoot = $('<tfoot/>').appendTo($this);
1272.
                }
1273.
            
1274.
                if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
1275.
                    $this.addClass( oClasses.sNoFooter );
1276.
                }
1277.
                else if ( tfoot.length > 0 ) {
1278.
                    oSettings.nTFoot = tfoot[0];
1279.
                    _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
1280.
                }
1281.
            
1282.
                /* Check if there is data passing into the constructor */
1283.
                if ( oInit.aaData ) {
1284.
                    for ( i=0 ; i<oInit.aaData.length ; i++ ) {
1285.
                        _fnAddData( oSettings, oInit.aaData[ i ] );
1286.
                    }
1287.
                }
1288.
                else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
1289.
                    /* Grab the data from the page - only do this when deferred loading or no Ajax
1290.
                     * source since there is no point in reading the DOM data if we are then going
1291.
                     * to replace it with Ajax data
1292.
                     */
1293.
                    _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
1294.
                }
1295.
            
1296.
                /* Copy the data index array */
1297.
                oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1298.
            
1299.
                /* Initialisation complete - table can be drawn */
1300.
                oSettings.bInitialised = true;
1301.
            
1302.
                /* Check if we need to initialise the table (it might not have been handed off to the
1303.
                 * language processor)
1304.
                 */
1305.
                if ( bInitHandedOff === false ) {
1306.
                    _fnInitialise( oSettings );
1307.
                }
1308.
            };
1309.
            
1310.
            /* Must be done after everything which can be overridden by the state saving! */
1311.
            if ( oInit.bStateSave )
1312.
            {
1313.
                features.bStateSave = true;
1314.
                _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
1315.
                _fnLoadState( oSettings, oInit, loadedInit );
1316.
            }
1317.
            else {
1318.
                loadedInit();
1319.
            }
1320.
            
1321.
        } );
1322.
        _that = null;
1323.
        return this;
1324.
    };
1325.
 
1326.
    
1327.
    /*
1328.
     * It is useful to have variables which are scoped locally so only the
1329.
     * DataTables functions can access them and they don't leak into global space.
1330.
     * At the same time these functions are often useful over multiple files in the
1331.
     * core and API, so we list, or at least document, all variables which are used
1332.
     * by DataTables as private variables here. This also ensures that there is no
1333.
     * clashing of variable names and that they can easily referenced for reuse.
1334.
     */
1335.
    
1336.
    
1337.
    // Defined else where
1338.
    //  _selector_run
1339.
    //  _selector_opts
1340.
    //  _selector_first
1341.
    //  _selector_row_indexes
1342.
    
1343.
    var _ext; // DataTable.ext
1344.
    var _Api; // DataTable.Api
1345.
    var _api_register; // DataTable.Api.register
1346.
    var _api_registerPlural; // DataTable.Api.registerPlural
1347.
    
1348.
    var _re_dic = {};
1349.
    var _re_new_lines = /[\r\n\u2028]/g;
1350.
    var _re_html = /<.*?>/g;
1351.
    
1352.
    // This is not strict ISO8601 - Date.parse() is quite lax, although
1353.
    // implementations differ between browsers.
1354.
    var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1355.
    
1356.
    // Escape regular expression special characters
1357.
    var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
1358.
    
1359.
    // http://en.wikipedia.org/wiki/Foreign_exchange_market
1360.
    // - \u20BD - Russian ruble.
1361.
    // - \u20a9 - South Korean Won
1362.
    // - \u20BA - Turkish Lira
1363.
    // - \u20B9 - Indian Rupee
1364.
    // - R - Brazil (R$) and South Africa
1365.
    // - fr - Swiss Franc
1366.
    // - kr - Swedish krona, Norwegian krone and Danish krone
1367.
    // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1368.
    // - Ƀ - Bitcoin
1369.
    // - Ξ - Ethereum
1370.
    //   standards as thousands separators.
1371.
    var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
1372.
    
1373.
    
1374.
    var _empty = function ( d ) {
1375.
        return !d || d === true || d === '-' ? true : false;
1376.
    };
1377.
    
1378.
    
1379.
    var _intVal = function ( s ) {
1380.
        var integer = parseInt( s, 10 );
1381.
        return !isNaN(integer) && isFinite(s) ? integer : null;
1382.
    };
1383.
    
1384.
    // Convert from a formatted number with characters other than `.` as the
1385.
    // decimal place, to a Javascript number
1386.
    var _numToDecimal = function ( num, decimalPoint ) {
1387.
        // Cache created regular expressions for speed as this function is called often
1388.
        if ( ! _re_dic[ decimalPoint ] ) {
1389.
            _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
1390.
        }
1391.
        return typeof num === 'string' && decimalPoint !== '.' ?
1392.
            num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
1393.
            num;
1394.
    };
1395.
    
1396.
    
1397.
    var _isNumber = function ( d, decimalPoint, formatted ) {
1398.
        var strType = typeof d === 'string';
1399.
    
1400.
        // If empty return immediately so there must be a number if it is a
1401.
        // formatted string (this stops the string "k", or "kr", etc being detected
1402.
        // as a formatted number for currency
1403.
        if ( _empty( d ) ) {
1404.
            return true;
1405.
        }
1406.
    
1407.
        if ( decimalPoint && strType ) {
1408.
            d = _numToDecimal( d, decimalPoint );
1409.
        }
1410.
    
1411.
        if ( formatted && strType ) {
1412.
            d = d.replace( _re_formatted_numeric, '' );
1413.
        }
1414.
    
1415.
        return !isNaN( parseFloat(d) ) && isFinite( d );
1416.
    };
1417.
    
1418.
    
1419.
    // A string without HTML in it can be considered to be HTML still
1420.
    var _isHtml = function ( d ) {
1421.
        return _empty( d ) || typeof d === 'string';
1422.
    };
1423.
    
1424.
    
1425.
    var _htmlNumeric = function ( d, decimalPoint, formatted ) {
1426.
        if ( _empty( d ) ) {
1427.
            return true;
1428.
        }
1429.
    
1430.
        var html = _isHtml( d );
1431.
        return ! html ?
1432.
            null :
1433.
            _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
1434.
                true :
1435.
                null;
1436.
    };
1437.
    
1438.
    
1439.
    var _pluck = function ( a, prop, prop2 ) {
1440.
        var out = [];
1441.
        var i=0, ien=a.length;
1442.
    
1443.
        // Could have the test in the loop for slightly smaller code, but speed
1444.
        // is essential here
1445.
        if ( prop2 !== undefined ) {
1446.
            for ( ; i<ien ; i++ ) {
1447.
                if ( a[i] && a[i][ prop ] ) {
1448.
                    out.push( a[i][ prop ][ prop2 ] );
1449.
                }
1450.
            }
1451.
        }
1452.
        else {
1453.
            for ( ; i<ien ; i++ ) {
1454.
                if ( a[i] ) {
1455.
                    out.push( a[i][ prop ] );
1456.
                }
1457.
            }
1458.
        }
1459.
    
1460.
        return out;
1461.
    };
1462.
    
1463.
    
1464.
    // Basically the same as _pluck, but rather than looping over `a` we use `order`
1465.
    // as the indexes to pick from `a`
1466.
    var _pluck_order = function ( a, order, prop, prop2 )
1467.
    {
1468.
        var out = [];
1469.
        var i=0, ien=order.length;
1470.
    
1471.
        // Could have the test in the loop for slightly smaller code, but speed
1472.
        // is essential here
1473.
        if ( prop2 !== undefined ) {
1474.
            for ( ; i<ien ; i++ ) {
1475.
                if ( a[ order[i] ][ prop ] ) {
1476.
                    out.push( a[ order[i] ][ prop ][ prop2 ] );
1477.
                }
1478.
            }
1479.
        }
1480.
        else {
1481.
            for ( ; i<ien ; i++ ) {
1482.
                out.push( a[ order[i] ][ prop ] );
1483.
            }
1484.
        }
1485.
    
1486.
        return out;
1487.
    };
1488.
    
1489.
    
1490.
    var _range = function ( len, start )
1491.
    {
1492.
        var out = [];
1493.
        var end;
1494.
    
1495.
        if ( start === undefined ) {
1496.
            start = 0;
1497.
            end = len;
1498.
        }
1499.
        else {
1500.
            end = start;
1501.
            start = len;
1502.
        }
1503.
    
1504.
        for ( var i=start ; i<end ; i++ ) {
1505.
            out.push( i );
1506.
        }
1507.
    
1508.
        return out;
1509.
    };
1510.
    
1511.
    
1512.
    var _removeEmpty = function ( a )
1513.
    {
1514.
        var out = [];
1515.
    
1516.
        for ( var i=0, ien=a.length ; i<ien ; i++ ) {
1517.
            if ( a[i] ) { // careful - will remove all falsy values!
1518.
                out.push( a[i] );
1519.
            }
1520.
        }
1521.
    
1522.
        return out;
1523.
    };
1524.
    
1525.
    
1526.
    var _stripHtml = function ( d ) {
1527.
        return d.replace( _re_html, '' );
1528.
    };
1529.
    
1530.
    
1531.
    /**
1532.
     * Determine if all values in the array are unique. This means we can short
1533.
     * cut the _unique method at the cost of a single loop. A sorted array is used
1534.
     * to easily check the values.
1535.
     *
1536.
     * @param  {array} src Source array
1537.
     * @return {boolean} true if all unique, false otherwise
1538.
     * @ignore
1539.
     */
1540.
    var _areAllUnique = function ( src ) {
1541.
        if ( src.length < 2 ) {
1542.
            return true;
1543.
        }
1544.
    
1545.
        var sorted = src.slice().sort();
1546.
        var last = sorted[0];
1547.
    
1548.
        for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
1549.
            if ( sorted[i] === last ) {
1550.
                return false;
1551.
            }
1552.
    
1553.
            last = sorted[i];
1554.
        }
1555.
    
1556.
        return true;
1557.
    };
1558.
    
1559.
    
1560.
    /**
1561.
     * Find the unique elements in a source array.
1562.
     *
1563.
     * @param  {array} src Source array
1564.
     * @return {array} Array of unique items
1565.
     * @ignore
1566.
     */
1567.
    var _unique = function ( src )
1568.
    {
1569.
        if ( _areAllUnique( src ) ) {
1570.
            return src.slice();
1571.
        }
1572.
    
1573.
        // A faster unique method is to use object keys to identify used values,
1574.
        // but this doesn't work with arrays or objects, which we must also
1575.
        // consider. See jsperf.com/compare-array-unique-versions/4 for more
1576.
        // information.
1577.
        var
1578.
            out = [],
1579.
            val,
1580.
            i, ien=src.length,
1581.
            j, k=0;
1582.
    
1583.
        again: for ( i=0 ; i<ien ; i++ ) {
1584.
            val = src[i];
1585.
    
1586.
            for ( j=0 ; j<k ; j++ ) {
1587.
                if ( out[j] === val ) {
1588.
                    continue again;
1589.
                }
1590.
            }
1591.
    
1592.
            out.push( val );
1593.
            k++;
1594.
        }
1595.
    
1596.
        return out;
1597.
    };
1598.
    
1599.
    
1600.
    /**
1601.
     * DataTables utility methods
1602.
     * 
1603.
     * This namespace provides helper methods that DataTables uses internally to
1604.
     * create a DataTable, but which are not exclusively used only for DataTables.
1605.
     * These methods can be used by extension authors to save the duplication of
1606.
     * code.
1607.
     *
1608.
     *  @namespace
1609.
     */
1610.
    DataTable.util = {
1611.
        /**
1612.
         * Throttle the calls to a function. Arguments and context are maintained
1613.
         * for the throttled function.
1614.
         *
1615.
         * @param {function} fn Function to be called
1616.
         * @param {integer} freq Call frequency in mS
1617.
         * @return {function} Wrapped function
1618.
         */
1619.
        throttle: function ( fn, freq ) {
1620.
            var
1621.
                frequency = freq !== undefined ? freq : 200,
1622.
                last,
1623.
                timer;
1624.
    
1625.
            return function () {
1626.
                var
1627.
                    that = this,
1628.
                    now  = +new Date(),
1629.
                    args = arguments;
1630.
    
1631.
                if ( last && now < last + frequency ) {
1632.
                    clearTimeout( timer );
1633.
    
1634.
                    timer = setTimeout( function () {
1635.
                        last = undefined;
1636.
                        fn.apply( that, args );
1637.
                    }, frequency );
1638.
                }
1639.
                else {
1640.
                    last = now;
1641.
                    fn.apply( that, args );
1642.
                }
1643.
            };
1644.
        },
1645.
    
1646.
    
1647.
        /**
1648.
         * Escape a string such that it can be used in a regular expression
1649.
         *
1650.
         *  @param {string} val string to escape
1651.
         *  @returns {string} escaped string
1652.
         */
1653.
        escapeRegex: function ( val ) {
1654.
            return val.replace( _re_escape_regex, '\\$1' );
1655.
        }
1656.
    };
1657.
    
1658.
    
1659.
    
1660.
    /**
1661.
     * Create a mapping object that allows camel case parameters to be looked up
1662.
     * for their Hungarian counterparts. The mapping is stored in a private
1663.
     * parameter called `_hungarianMap` which can be accessed on the source object.
1664.
     *  @param {object} o
1665.
     *  @memberof DataTable#oApi
1666.
     */
1667.
    function _fnHungarianMap ( o )
1668.
    {
1669.
        var
1670.
            hungarian = 'a aa ai ao as b fn i m o s ',
1671.
            match,
1672.
            newKey,
1673.
            map = {};
1674.
    
1675.
        $.each( o, function (key, val) {
1676.
            match = key.match(/^([^A-Z]+?)([A-Z])/);
1677.
    
1678.
            if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
1679.
            {
1680.
                newKey = key.replace( match[0], match[2].toLowerCase() );
1681.
                map[ newKey ] = key;
1682.
    
1683.
                if ( match[1] === 'o' )
1684.
                {
1685.
                    _fnHungarianMap( o[key] );
1686.
                }
1687.
            }
1688.
        } );
1689.
    
1690.
        o._hungarianMap = map;
1691.
    }
1692.
    
1693.
    
1694.
    /**
1695.
     * Convert from camel case parameters to Hungarian, based on a Hungarian map
1696.
     * created by _fnHungarianMap.
1697.
     *  @param {object} src The model object which holds all parameters that can be
1698.
     *    mapped.
1699.
     *  @param {object} user The object to convert from camel case to Hungarian.
1700.
     *  @param {boolean} force When set to `true`, properties which already have a
1701.
     *    Hungarian value in the `user` object will be overwritten. Otherwise they
1702.
     *    won't be.
1703.
     *  @memberof DataTable#oApi
1704.
     */
1705.
    function _fnCamelToHungarian ( src, user, force )
1706.
    {
1707.
        if ( ! src._hungarianMap ) {
1708.
            _fnHungarianMap( src );
1709.
        }
1710.
    
1711.
        var hungarianKey;
1712.
    
1713.
        $.each( user, function (key, val) {
1714.
            hungarianKey = src._hungarianMap[ key ];
1715.
    
1716.
            if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
1717.
            {
1718.
                // For objects, we need to buzz down into the object to copy parameters
1719.
                if ( hungarianKey.charAt(0) === 'o' )
1720.
                {
1721.
                    // Copy the camelCase options over to the hungarian
1722.
                    if ( ! user[ hungarianKey ] ) {
1723.
                        user[ hungarianKey ] = {};
1724.
                    }
1725.
                    $.extend( true, user[hungarianKey], user[key] );
1726.
    
1727.
                    _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
1728.
                }
1729.
                else {
1730.
                    user[hungarianKey] = user[ key ];
1731.
                }
1732.
            }
1733.
        } );
1734.
    }
1735.
    
1736.
    
1737.
    /**
1738.
     * Language compatibility - when certain options are given, and others aren't, we
1739.
     * need to duplicate the values over, in order to provide backwards compatibility
1740.
     * with older language files.
1741.
     *  @param {object} oSettings dataTables settings object
1742.
     *  @memberof DataTable#oApi
1743.
     */
1744.
    function _fnLanguageCompat( lang )
1745.
    {
1746.
        // Note the use of the Hungarian notation for the parameters in this method as
1747.
        // this is called after the mapping of camelCase to Hungarian
1748.
        var defaults = DataTable.defaults.oLanguage;
1749.
    
1750.
        // Default mapping
1751.
        var defaultDecimal = defaults.sDecimal;
1752.
        if ( defaultDecimal ) {
1753.
            _addNumericSort( defaultDecimal );
1754.
        }
1755.
    
1756.
        if ( lang ) {
1757.
            var zeroRecords = lang.sZeroRecords;
1758.
    
1759.
            // Backwards compatibility - if there is no sEmptyTable given, then use the same as
1760.
            // sZeroRecords - assuming that is given.
1761.
            if ( ! lang.sEmptyTable && zeroRecords &&
1762.
                defaults.sEmptyTable === "No data available in table" )
1763.
            {
1764.
                _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
1765.
            }
1766.
    
1767.
            // Likewise with loading records
1768.
            if ( ! lang.sLoadingRecords && zeroRecords &&
1769.
                defaults.sLoadingRecords === "Loading..." )
1770.
            {
1771.
                _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
1772.
            }
1773.
    
1774.
            // Old parameter name of the thousands separator mapped onto the new
1775.
            if ( lang.sInfoThousands ) {
1776.
                lang.sThousands = lang.sInfoThousands;
1777.
            }
1778.
    
1779.
            var decimal = lang.sDecimal;
1780.
            if ( decimal && defaultDecimal !== decimal ) {
1781.
                _addNumericSort( decimal );
1782.
            }
1783.
        }
1784.
    }
1785.
    
1786.
    
1787.
    /**
1788.
     * Map one parameter onto another
1789.
     *  @param {object} o Object to map
1790.
     *  @param {*} knew The new parameter name
1791.
     *  @param {*} old The old parameter name
1792.
     */
1793.
    var _fnCompatMap = function ( o, knew, old ) {
1794.
        if ( o[ knew ] !== undefined ) {
1795.
            o[ old ] = o[ knew ];
1796.
        }
1797.
    };
1798.
    
1799.
    
1800.
    /**
1801.
     * Provide backwards compatibility for the main DT options. Note that the new
1802.
     * options are mapped onto the old parameters, so this is an external interface
1803.
     * change only.
1804.
     *  @param {object} init Object to map
1805.
     */
1806.
    function _fnCompatOpts ( init )
1807.
    {
1808.
        _fnCompatMap( init, 'ordering',      'bSort' );
1809.
        _fnCompatMap( init, 'orderMulti',    'bSortMulti' );
1810.
        _fnCompatMap( init, 'orderClasses',  'bSortClasses' );
1811.
        _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
1812.
        _fnCompatMap( init, 'order',         'aaSorting' );
1813.
        _fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
1814.
        _fnCompatMap( init, 'paging',        'bPaginate' );
1815.
        _fnCompatMap( init, 'pagingType',    'sPaginationType' );
1816.
        _fnCompatMap( init, 'pageLength',    'iDisplayLength' );
1817.
        _fnCompatMap( init, 'searching',     'bFilter' );
1818.
    
1819.
        // Boolean initialisation of x-scrolling
1820.
        if ( typeof init.sScrollX === 'boolean' ) {
1821.
            init.sScrollX = init.sScrollX ? '100%' : '';
1822.
        }
1823.
        if ( typeof init.scrollX === 'boolean' ) {
1824.
            init.scrollX = init.scrollX ? '100%' : '';
1825.
        }
1826.
    
1827.
        // Column search objects are in an array, so it needs to be converted
1828.
        // element by element
1829.
        var searchCols = init.aoSearchCols;
1830.
    
1831.
        if ( searchCols ) {
1832.
            for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
1833.
                if ( searchCols[i] ) {
1834.
                    _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
1835.
                }
1836.
            }
1837.
        }
1838.
    }
1839.
    
1840.
    
1841.
    /**
1842.
     * Provide backwards compatibility for column options. Note that the new options
1843.
     * are mapped onto the old parameters, so this is an external interface change
1844.
     * only.
1845.
     *  @param {object} init Object to map
1846.
     */
1847.
    function _fnCompatCols ( init )
1848.
    {
1849.
        _fnCompatMap( init, 'orderable',     'bSortable' );
1850.
        _fnCompatMap( init, 'orderData',     'aDataSort' );
1851.
        _fnCompatMap( init, 'orderSequence', 'asSorting' );
1852.
        _fnCompatMap( init, 'orderDataType', 'sortDataType' );
1853.
    
1854.
        // orderData can be given as an integer
1855.
        var dataSort = init.aDataSort;
1856.
        if ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {
1857.
            init.aDataSort = [ dataSort ];
1858.
        }
1859.
    }
1860.
    
1861.
    
1862.
    /**
1863.
     * Browser feature detection for capabilities, quirks
1864.
     *  @param {object} settings dataTables settings object
1865.
     *  @memberof DataTable#oApi
1866.
     */
1867.
    function _fnBrowserDetect( settings )
1868.
    {
1869.
        // We don't need to do this every time DataTables is constructed, the values
1870.
        // calculated are specific to the browser and OS configuration which we
1871.
        // don't expect to change between initialisations
1872.
        if ( ! DataTable.__browser ) {
1873.
            var browser = {};
1874.
            DataTable.__browser = browser;
1875.
    
1876.
            // Scrolling feature / quirks detection
1877.
            var n = $('<div/>')
1878.
                .css( {
1879.
                    position: 'fixed',
1880.
                    top: 0,
1881.
                    left: $(window).scrollLeft()*-1, // allow for scrolling
1882.
                    height: 1,
1883.
                    width: 1,
1884.
                    overflow: 'hidden'
1885.
                } )
1886.
                .append(
1887.
                    $('<div/>')
1888.
                        .css( {
1889.
                            position: 'absolute',
1890.
                            top: 1,
1891.
                            left: 1,
1892.
                            width: 100,
1893.
                            overflow: 'scroll'
1894.
                        } )
1895.
                        .append(
1896.
                            $('<div/>')
1897.
                                .css( {
1898.
                                    width: '100%',
1899.
                                    height: 10
1900.
                                } )
1901.
                        )
1902.
                )
1903.
                .appendTo( 'body' );
1904.
    
1905.
            var outer = n.children();
1906.
            var inner = outer.children();
1907.
    
1908.
            // Numbers below, in order, are:
1909.
            // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
1910.
            //
1911.
            // IE6 XP:                           100 100 100  83
1912.
            // IE7 Vista:                        100 100 100  83
1913.
            // IE 8+ Windows:                     83  83 100  83
1914.
            // Evergreen Windows:                 83  83 100  83
1915.
            // Evergreen Mac with scrollbars:     85  85 100  85
1916.
            // Evergreen Mac without scrollbars: 100 100 100 100
1917.
    
1918.
            // Get scrollbar width
1919.
            browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
1920.
    
1921.
            // IE6/7 will oversize a width 100% element inside a scrolling element, to
1922.
            // include the width of the scrollbar, while other browsers ensure the inner
1923.
            // element is contained without forcing scrolling
1924.
            browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
1925.
    
1926.
            // In rtl text layout, some browsers (most, but not all) will place the
1927.
            // scrollbar on the left, rather than the right.
1928.
            browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
1929.
    
1930.
            // IE8- don't provide height and width for getBoundingClientRect
1931.
            browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
1932.
    
1933.
            n.remove();
1934.
        }
1935.
    
1936.
        $.extend( settings.oBrowser, DataTable.__browser );
1937.
        settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
1938.
    }
1939.
    
1940.
    
1941.
    /**
1942.
     * Array.prototype reduce[Right] method, used for browsers which don't support
1943.
     * JS 1.6. Done this way to reduce code size, since we iterate either way
1944.
     *  @param {object} settings dataTables settings object
1945.
     *  @memberof DataTable#oApi
1946.
     */
1947.
    function _fnReduce ( that, fn, init, start, end, inc )
1948.
    {
1949.
        var
1950.
            i = start,
1951.
            value,
1952.
            isSet = false;
1953.
    
1954.
        if ( init !== undefined ) {
1955.
            value = init;
1956.
            isSet = true;
1957.
        }
1958.
    
1959.
        while ( i !== end ) {
1960.
            if ( ! that.hasOwnProperty(i) ) {
1961.
                continue;
1962.
            }
1963.
    
1964.
            value = isSet ?
1965.
                fn( value, that[i], i, that ) :
1966.
                that[i];
1967.
    
1968.
            isSet = true;
1969.
            i += inc;
1970.
        }
1971.
    
1972.
        return value;
1973.
    }
1974.
    
1975.
    /**
1976.
     * Add a column to the list used for the table with default values
1977.
     *  @param {object} oSettings dataTables settings object
1978.
     *  @param {node} nTh The th element for this column
1979.
     *  @memberof DataTable#oApi
1980.
     */
1981.
    function _fnAddColumn( oSettings, nTh )
1982.
    {
1983.
        // Add column to aoColumns array
1984.
        var oDefaults = DataTable.defaults.column;
1985.
        var iCol = oSettings.aoColumns.length;
1986.
        var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
1987.
            "nTh": nTh ? nTh : document.createElement('th'),
1988.
            "sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
1989.
            "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
1990.
            "mData": oDefaults.mData ? oDefaults.mData : iCol,
1991.
            idx: iCol
1992.
        } );
1993.
        oSettings.aoColumns.push( oCol );
1994.
    
1995.
        // Add search object for column specific search. Note that the `searchCols[ iCol ]`
1996.
        // passed into extend can be undefined. This allows the user to give a default
1997.
        // with only some of the parameters defined, and also not give a default
1998.
        var searchCols = oSettings.aoPreSearchCols;
1999.
        searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
2000.
    
2001.
        // Use the default column options function to initialise classes etc
2002.
        _fnColumnOptions( oSettings, iCol, $(nTh).data() );
2003.
    }
2004.
    
2005.
    
2006.
    /**
2007.
     * Apply options for a column
2008.
     *  @param {object} oSettings dataTables settings object
2009.
     *  @param {int} iCol column index to consider
2010.
     *  @param {object} oOptions object with sType, bVisible and bSearchable etc
2011.
     *  @memberof DataTable#oApi
2012.
     */
2013.
    function _fnColumnOptions( oSettings, iCol, oOptions )
2014.
    {
2015.
        var oCol = oSettings.aoColumns[ iCol ];
2016.
        var oClasses = oSettings.oClasses;
2017.
        var th = $(oCol.nTh);
2018.
    
2019.
        // Try to get width information from the DOM. We can't get it from CSS
2020.
        // as we'd need to parse the CSS stylesheet. `width` option can override
2021.
        if ( ! oCol.sWidthOrig ) {
2022.
            // Width attribute
2023.
            oCol.sWidthOrig = th.attr('width') || null;
2024.
    
2025.
            // Style attribute
2026.
            var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
2027.
            if ( t ) {
2028.
                oCol.sWidthOrig = t[1];
2029.
            }
2030.
        }
2031.
    
2032.
        /* User specified column options */
2033.
        if ( oOptions !== undefined && oOptions !== null )
2034.
        {
2035.
            // Backwards compatibility
2036.
            _fnCompatCols( oOptions );
2037.
    
2038.
            // Map camel case parameters to their Hungarian counterparts
2039.
            _fnCamelToHungarian( DataTable.defaults.column, oOptions, true );
2040.
    
2041.
            /* Backwards compatibility for mDataProp */
2042.
            if ( oOptions.mDataProp !== undefined && !oOptions.mData )
2043.
            {
2044.
                oOptions.mData = oOptions.mDataProp;
2045.
            }
2046.
    
2047.
            if ( oOptions.sType )
2048.
            {
2049.
                oCol._sManualType = oOptions.sType;
2050.
            }
2051.
    
2052.
            // `class` is a reserved word in Javascript, so we need to provide
2053.
            // the ability to use a valid name for the camel case input
2054.
            if ( oOptions.className && ! oOptions.sClass )
2055.
            {
2056.
                oOptions.sClass = oOptions.className;
2057.
            }
2058.
            if ( oOptions.sClass ) {
2059.
                th.addClass( oOptions.sClass );
2060.
            }
2061.
    
2062.
            $.extend( oCol, oOptions );
2063.
            _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
2064.
    
2065.
            /* iDataSort to be applied (backwards compatibility), but aDataSort will take
2066.
             * priority if defined
2067.
             */
2068.
            if ( oOptions.iDataSort !== undefined )
2069.
            {
2070.
                oCol.aDataSort = [ oOptions.iDataSort ];
2071.
            }
2072.
            _fnMap( oCol, oOptions, "aDataSort" );
2073.
        }
2074.
    
2075.
        /* Cache the data get and set functions for speed */
2076.
        var mDataSrc = oCol.mData;
2077.
        var mData = _fnGetObjectDataFn( mDataSrc );
2078.
        var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
2079.
    
2080.
        var attrTest = function( src ) {
2081.
            return typeof src === 'string' && src.indexOf('@') !== -1;
2082.
        };
2083.
        oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
2084.
            attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
2085.
        );
2086.
        oCol._setter = null;
2087.
    
2088.
        oCol.fnGetData = function (rowData, type, meta) {
2089.
            var innerData = mData( rowData, type, undefined, meta );
2090.
    
2091.
            return mRender && type ?
2092.
                mRender( innerData, type, rowData, meta ) :
2093.
                innerData;
2094.
        };
2095.
        oCol.fnSetData = function ( rowData, val, meta ) {
2096.
            return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
2097.
        };
2098.
    
2099.
        // Indicate if DataTables should read DOM data as an object or array
2100.
        // Used in _fnGetRowElements
2101.
        if ( typeof mDataSrc !== 'number' ) {
2102.
            oSettings._rowReadObject = true;
2103.
        }
2104.
    
2105.
        /* Feature sorting overrides column specific when off */
2106.
        if ( !oSettings.oFeatures.bSort )
2107.
        {
2108.
            oCol.bSortable = false;
2109.
            th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
2110.
        }
2111.
    
2112.
        /* Check that the class assignment is correct for sorting */
2113.
        var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
2114.
        var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
2115.
        if ( !oCol.bSortable || (!bAsc && !bDesc) )
2116.
        {
2117.
            oCol.sSortingClass = oClasses.sSortableNone;
2118.
            oCol.sSortingClassJUI = "";
2119.
        }
2120.
        else if ( bAsc && !bDesc )
2121.
        {
2122.
            oCol.sSortingClass = oClasses.sSortableAsc;
2123.
            oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
2124.
        }
2125.
        else if ( !bAsc && bDesc )
2126.
        {
2127.
            oCol.sSortingClass = oClasses.sSortableDesc;
2128.
            oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
2129.
        }
2130.
        else
2131.
        {
2132.
            oCol.sSortingClass = oClasses.sSortable;
2133.
            oCol.sSortingClassJUI = oClasses.sSortJUI;
2134.
        }
2135.
    }
2136.
    
2137.
    
2138.
    /**
2139.
     * Adjust the table column widths for new data. Note: you would probably want to
2140.
     * do a redraw after calling this function!
2141.
     *  @param {object} settings dataTables settings object
2142.
     *  @memberof DataTable#oApi
2143.
     */
2144.
    function _fnAdjustColumnSizing ( settings )
2145.
    {
2146.
        /* Not interested in doing column width calculation if auto-width is disabled */
2147.
        if ( settings.oFeatures.bAutoWidth !== false )
2148.
        {
2149.
            var columns = settings.aoColumns;
2150.
    
2151.
            _fnCalculateColumnWidths( settings );
2152.
            for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
2153.
            {
2154.
                columns[i].nTh.style.width = columns[i].sWidth;
2155.
            }
2156.
        }
2157.
    
2158.
        var scroll = settings.oScroll;
2159.
        if ( scroll.sY !== '' || scroll.sX !== '')
2160.
        {
2161.
            _fnScrollDraw( settings );
2162.
        }
2163.
    
2164.
        _fnCallbackFire( settings, null, 'column-sizing', [settings] );
2165.
    }
2166.
    
2167.
    
2168.
    /**
2169.
     * Covert the index of a visible column to the index in the data array (take account
2170.
     * of hidden columns)
2171.
     *  @param {object} oSettings dataTables settings object
2172.
     *  @param {int} iMatch Visible column index to lookup
2173.
     *  @returns {int} i the data index
2174.
     *  @memberof DataTable#oApi
2175.
     */
2176.
    function _fnVisibleToColumnIndex( oSettings, iMatch )
2177.
    {
2178.
        var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2179.
    
2180.
        return typeof aiVis[iMatch] === 'number' ?
2181.
            aiVis[iMatch] :
2182.
            null;
2183.
    }
2184.
    
2185.
    
2186.
    /**
2187.
     * Covert the index of an index in the data array and convert it to the visible
2188.
     *   column index (take account of hidden columns)
2189.
     *  @param {int} iMatch Column index to lookup
2190.
     *  @param {object} oSettings dataTables settings object
2191.
     *  @returns {int} i the data index
2192.
     *  @memberof DataTable#oApi
2193.
     */
2194.
    function _fnColumnIndexToVisible( oSettings, iMatch )
2195.
    {
2196.
        var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2197.
        var iPos = $.inArray( iMatch, aiVis );
2198.
    
2199.
        return iPos !== -1 ? iPos : null;
2200.
    }
2201.
    
2202.
    
2203.
    /**
2204.
     * Get the number of visible columns
2205.
     *  @param {object} oSettings dataTables settings object
2206.
     *  @returns {int} i the number of visible columns
2207.
     *  @memberof DataTable#oApi
2208.
     */
2209.
    function _fnVisbleColumns( oSettings )
2210.
    {
2211.
        var vis = 0;
2212.
    
2213.
        // No reduce in IE8, use a loop for now
2214.
        $.each( oSettings.aoColumns, function ( i, col ) {
2215.
            if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
2216.
                vis++;
2217.
            }
2218.
        } );
2219.
    
2220.
        return vis;
2221.
    }
2222.
    
2223.
    
2224.
    /**
2225.
     * Get an array of column indexes that match a given property
2226.
     *  @param {object} oSettings dataTables settings object
2227.
     *  @param {string} sParam Parameter in aoColumns to look for - typically
2228.
     *    bVisible or bSearchable
2229.
     *  @returns {array} Array of indexes with matched properties
2230.
     *  @memberof DataTable#oApi
2231.
     */
2232.
    function _fnGetColumns( oSettings, sParam )
2233.
    {
2234.
        var a = [];
2235.
    
2236.
        $.map( oSettings.aoColumns, function(val, i) {
2237.
            if ( val[sParam] ) {
2238.
                a.push( i );
2239.
            }
2240.
        } );
2241.
    
2242.
        return a;
2243.
    }
2244.
    
2245.
    
2246.
    /**
2247.
     * Calculate the 'type' of a column
2248.
     *  @param {object} settings dataTables settings object
2249.
     *  @memberof DataTable#oApi
2250.
     */
2251.
    function _fnColumnTypes ( settings )
2252.
    {
2253.
        var columns = settings.aoColumns;
2254.
        var data = settings.aoData;
2255.
        var types = DataTable.ext.type.detect;
2256.
        var i, ien, j, jen, k, ken;
2257.
        var col, cell, detectedType, cache;
2258.
    
2259.
        // For each column, spin over the 
2260.
        for ( i=0, ien=columns.length ; i<ien ; i++ ) {
2261.
            col = columns[i];
2262.
            cache = [];
2263.
    
2264.
            if ( ! col.sType && col._sManualType ) {
2265.
                col.sType = col._sManualType;
2266.
            }
2267.
            else if ( ! col.sType ) {
2268.
                for ( j=0, jen=types.length ; j<jen ; j++ ) {
2269.
                    for ( k=0, ken=data.length ; k<ken ; k++ ) {
2270.
                        // Use a cache array so we only need to get the type data
2271.
                        // from the formatter once (when using multiple detectors)
2272.
                        if ( cache[k] === undefined ) {
2273.
                            cache[k] = _fnGetCellData( settings, k, i, 'type' );
2274.
                        }
2275.
    
2276.
                        detectedType = types[j]( cache[k], settings );
2277.
    
2278.
                        // If null, then this type can't apply to this column, so
2279.
                        // rather than testing all cells, break out. There is an
2280.
                        // exception for the last type which is `html`. We need to
2281.
                        // scan all rows since it is possible to mix string and HTML
2282.
                        // types
2283.
                        if ( ! detectedType && j !== types.length-1 ) {
2284.
                            break;
2285.
                        }
2286.
    
2287.
                        // Only a single match is needed for html type since it is
2288.
                        // bottom of the pile and very similar to string
2289.
                        if ( detectedType === 'html' ) {
2290.
                            break;
2291.
                        }
2292.
                    }
2293.
    
2294.
                    // Type is valid for all data points in the column - use this
2295.
                    // type
2296.
                    if ( detectedType ) {
2297.
                        col.sType = detectedType;
2298.
                        break;
2299.
                    }
2300.
                }
2301.
    
2302.
                // Fall back - if no type was detected, always use string
2303.
                if ( ! col.sType ) {
2304.
                    col.sType = 'string';
2305.
                }
2306.
            }
2307.
        }
2308.
    }
2309.
    
2310.
    
2311.
    /**
2312.
     * Take the column definitions and static columns arrays and calculate how
2313.
     * they relate to column indexes. The callback function will then apply the
2314.
     * definition found for a column to a suitable configuration object.
2315.
     *  @param {object} oSettings dataTables settings object
2316.
     *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
2317.
     *  @param {array} aoCols The aoColumns array that defines columns individually
2318.
     *  @param {function} fn Callback function - takes two parameters, the calculated
2319.
     *    column index and the definition for that column.
2320.
     *  @memberof DataTable#oApi
2321.
     */
2322.
    function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
2323.
    {
2324.
        var i, iLen, j, jLen, k, kLen, def;
2325.
        var columns = oSettings.aoColumns;
2326.
    
2327.
        // Column definitions with aTargets
2328.
        if ( aoColDefs )
2329.
        {
2330.
            /* Loop over the definitions array - loop in reverse so first instance has priority */
2331.
            for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
2332.
            {
2333.
                def = aoColDefs[i];
2334.
    
2335.
                /* Each definition can target multiple columns, as it is an array */
2336.
                var aTargets = def.targets !== undefined ?
2337.
                    def.targets :
2338.
                    def.aTargets;
2339.
    
2340.
                if ( ! $.isArray( aTargets ) )
2341.
                {
2342.
                    aTargets = [ aTargets ];
2343.
                }
2344.
    
2345.
                for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
2346.
                {
2347.
                    if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
2348.
                    {
2349.
                        /* Add columns that we don't yet know about */
2350.
                        while( columns.length <= aTargets[j] )
2351.
                        {
2352.
                            _fnAddColumn( oSettings );
2353.
                        }
2354.
    
2355.
                        /* Integer, basic index */
2356.
                        fn( aTargets[j], def );
2357.
                    }
2358.
                    else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
2359.
                    {
2360.
                        /* Negative integer, right to left column counting */
2361.
                        fn( columns.length+aTargets[j], def );
2362.
                    }
2363.
                    else if ( typeof aTargets[j] === 'string' )
2364.
                    {
2365.
                        /* Class name matching on TH element */
2366.
                        for ( k=0, kLen=columns.length ; k<kLen ; k++ )
2367.
                        {
2368.
                            if ( aTargets[j] == "_all" ||
2369.
                                 $(columns[k].nTh).hasClass( aTargets[j] ) )
2370.
                            {
2371.
                                fn( k, def );
2372.
                            }
2373.
                        }
2374.
                    }
2375.
                }
2376.
            }
2377.
        }
2378.
    
2379.
        // Statically defined columns array
2380.
        if ( aoCols )
2381.
        {
2382.
            for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
2383.
            {
2384.
                fn( i, aoCols[i] );
2385.
            }
2386.
        }
2387.
    }
2388.
    
2389.
    /**
2390.
     * Add a data array to the table, creating DOM node etc. This is the parallel to
2391.
     * _fnGatherData, but for adding rows from a Javascript source, rather than a
2392.
     * DOM source.
2393.
     *  @param {object} oSettings dataTables settings object
2394.
     *  @param {array} aData data array to be added
2395.
     *  @param {node} [nTr] TR element to add to the table - optional. If not given,
2396.
     *    DataTables will create a row automatically
2397.
     *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
2398.
     *    if nTr is.
2399.
     *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
2400.
     *  @memberof DataTable#oApi
2401.
     */
2402.
    function _fnAddData ( oSettings, aDataIn, nTr, anTds )
2403.
    {
2404.
        /* Create the object for storing information about this new row */
2405.
        var iRow = oSettings.aoData.length;
2406.
        var oData = $.extend( true, {}, DataTable.models.oRow, {
2407.
            src: nTr ? 'dom' : 'data',
2408.
            idx: iRow
2409.
        } );
2410.
    
2411.
        oData._aData = aDataIn;
2412.
        oSettings.aoData.push( oData );
2413.
    
2414.
        /* Create the cells */
2415.
        var nTd, sThisType;
2416.
        var columns = oSettings.aoColumns;
2417.
    
2418.
        // Invalidate the column types as the new data needs to be revalidated
2419.
        for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
2420.
        {
2421.
            columns[i].sType = null;
2422.
        }
2423.
    
2424.
        /* Add to the display array */
2425.
        oSettings.aiDisplayMaster.push( iRow );
2426.
    
2427.
        var id = oSettings.rowIdFn( aDataIn );
2428.
        if ( id !== undefined ) {
2429.
            oSettings.aIds[ id ] = oData;
2430.
        }
2431.
    
2432.
        /* Create the DOM information, or register it if already present */
2433.
        if ( nTr || ! oSettings.oFeatures.bDeferRender )
2434.
        {
2435.
            _fnCreateTr( oSettings, iRow, nTr, anTds );
2436.
        }
2437.
    
2438.
        return iRow;
2439.
    }
2440.
    
2441.
    
2442.
    /**
2443.
     * Add one or more TR elements to the table. Generally we'd expect to
2444.
     * use this for reading data from a DOM sourced table, but it could be
2445.
     * used for an TR element. Note that if a TR is given, it is used (i.e.
2446.
     * it is not cloned).
2447.
     *  @param {object} settings dataTables settings object
2448.
     *  @param {array|node|jQuery} trs The TR element(s) to add to the table
2449.
     *  @returns {array} Array of indexes for the added rows
2450.
     *  @memberof DataTable#oApi
2451.
     */
2452.
    function _fnAddTr( settings, trs )
2453.
    {
2454.
        var row;
2455.
    
2456.
        // Allow an individual node to be passed in
2457.
        if ( ! (trs instanceof $) ) {
2458.
            trs = $(trs);
2459.
        }
2460.
    
2461.
        return trs.map( function (i, el) {
2462.
            row = _fnGetRowElements( settings, el );
2463.
            return _fnAddData( settings, row.data, el, row.cells );
2464.
        } );
2465.
    }
2466.
    
2467.
    
2468.
    /**
2469.
     * Take a TR element and convert it to an index in aoData
2470.
     *  @param {object} oSettings dataTables settings object
2471.
     *  @param {node} n the TR element to find
2472.
     *  @returns {int} index if the node is found, null if not
2473.
     *  @memberof DataTable#oApi
2474.
     */
2475.
    function _fnNodeToDataIndex( oSettings, n )
2476.
    {
2477.
        return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
2478.
    }
2479.
    
2480.
    
2481.
    /**
2482.
     * Take a TD element and convert it into a column data index (not the visible index)
2483.
     *  @param {object} oSettings dataTables settings object
2484.
     *  @param {int} iRow The row number the TD/TH can be found in
2485.
     *  @param {node} n The TD/TH element to find
2486.
     *  @returns {int} index if the node is found, -1 if not
2487.
     *  @memberof DataTable#oApi
2488.
     */
2489.
    function _fnNodeToColumnIndex( oSettings, iRow, n )
2490.
    {
2491.
        return $.inArray( n, oSettings.aoData[ iRow ].anCells );
2492.
    }
2493.
    
2494.
    
2495.
    /**
2496.
     * Get the data for a given cell from the internal cache, taking into account data mapping
2497.
     *  @param {object} settings dataTables settings object
2498.
     *  @param {int} rowIdx aoData row id
2499.
     *  @param {int} colIdx Column index
2500.
     *  @param {string} type data get type ('display', 'type' 'filter' 'sort')
2501.
     *  @returns {*} Cell data
2502.
     *  @memberof DataTable#oApi
2503.
     */
2504.
    function _fnGetCellData( settings, rowIdx, colIdx, type )
2505.
    {
2506.
        var draw           = settings.iDraw;
2507.
        var col            = settings.aoColumns[colIdx];
2508.
        var rowData        = settings.aoData[rowIdx]._aData;
2509.
        var defaultContent = col.sDefaultContent;
2510.
        var cellData       = col.fnGetData( rowData, type, {
2511.
            settings: settings,
2512.
            row:      rowIdx,
2513.
            col:      colIdx
2514.
        } );
2515.
    
2516.
        if ( cellData === undefined ) {
2517.
            if ( settings.iDrawError != draw && defaultContent === null ) {
2518.
                _fnLog( settings, 0, "Requested unknown parameter "+
2519.
                    (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
2520.
                    " for row "+rowIdx+", column "+colIdx, 4 );
2521.
                settings.iDrawError = draw;
2522.
            }
2523.
            return defaultContent;
2524.
        }
2525.
    
2526.
        // When the data source is null and a specific data type is requested (i.e.
2527.
        // not the original data), we can use default column data
2528.
        if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
2529.
            cellData = defaultContent;
2530.
        }
2531.
        else if ( typeof cellData === 'function' ) {
2532.
            // If the data source is a function, then we run it and use the return,
2533.
            // executing in the scope of the data object (for instances)
2534.
            return cellData.call( rowData );
2535.
        }
2536.
    
2537.
        if ( cellData === null && type == 'display' ) {
2538.
            return '';
2539.
        }
2540.
        return cellData;
2541.
    }
2542.
    
2543.
    
2544.
    /**
2545.
     * Set the value for a specific cell, into the internal data cache
2546.
     *  @param {object} settings dataTables settings object
2547.
     *  @param {int} rowIdx aoData row id
2548.
     *  @param {int} colIdx Column index
2549.
     *  @param {*} val Value to set
2550.
     *  @memberof DataTable#oApi
2551.
     */
2552.
    function _fnSetCellData( settings, rowIdx, colIdx, val )
2553.
    {
2554.
        var col     = settings.aoColumns[colIdx];
2555.
        var rowData = settings.aoData[rowIdx]._aData;
2556.
    
2557.
        col.fnSetData( rowData, val, {
2558.
            settings: settings,
2559.
            row:      rowIdx,
2560.
            col:      colIdx
2561.
        }  );
2562.
    }
2563.
    
2564.
    
2565.
    // Private variable that is used to match action syntax in the data property object
2566.
    var __reArray = /\[.*?\]$/;
2567.
    var __reFn = /\(\)$/;
2568.
    
2569.
    /**
2570.
     * Split string on periods, taking into account escaped periods
2571.
     * @param  {string} str String to split
2572.
     * @return {array} Split string
2573.
     */
2574.
    function _fnSplitObjNotation( str )
2575.
    {
2576.
        return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
2577.
            return s.replace(/\\\./g, '.');
2578.
        } );
2579.
    }
2580.
    
2581.
    
2582.
    /**
2583.
     * Return a function that can be used to get data from a source object, taking
2584.
     * into account the ability to use nested objects as a source
2585.
     *  @param {string|int|function} mSource The data source for the object
2586.
     *  @returns {function} Data get function
2587.
     *  @memberof DataTable#oApi
2588.
     */
2589.
    function _fnGetObjectDataFn( mSource )
2590.
    {
2591.
        if ( $.isPlainObject( mSource ) )
2592.
        {
2593.
            /* Build an object of get functions, and wrap them in a single call */
2594.
            var o = {};
2595.
            $.each( mSource, function (key, val) {
2596.
                if ( val ) {
2597.
                    o[key] = _fnGetObjectDataFn( val );
2598.
                }
2599.
            } );
2600.
    
2601.
            return function (data, type, row, meta) {
2602.
                var t = o[type] || o._;
2603.
                return t !== undefined ?
2604.
                    t(data, type, row, meta) :
2605.
                    data;
2606.
            };
2607.
        }
2608.
        else if ( mSource === null )
2609.
        {
2610.
            /* Give an empty string for rendering / sorting etc */
2611.
            return function (data) { // type, row and meta also passed, but not used
2612.
                return data;
2613.
            };
2614.
        }
2615.
        else if ( typeof mSource === 'function' )
2616.
        {
2617.
            return function (data, type, row, meta) {
2618.
                return mSource( data, type, row, meta );
2619.
            };
2620.
        }
2621.
        else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2622.
                  mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2623.
        {
2624.
            /* If there is a . in the source string then the data source is in a
2625.
             * nested object so we loop over the data for each level to get the next
2626.
             * level down. On each loop we test for undefined, and if found immediately
2627.
             * return. This allows entire objects to be missing and sDefaultContent to
2628.
             * be used if defined, rather than throwing an error
2629.
             */
2630.
            var fetchData = function (data, type, src) {
2631.
                var arrayNotation, funcNotation, out, innerSrc;
2632.
    
2633.
                if ( src !== "" )
2634.
                {
2635.
                    var a = _fnSplitObjNotation( src );
2636.
    
2637.
                    for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2638.
                    {
2639.
                        // Check if we are dealing with special notation
2640.
                        arrayNotation = a[i].match(__reArray);
2641.
                        funcNotation = a[i].match(__reFn);
2642.
    
2643.
                        if ( arrayNotation )
2644.
                        {
2645.
                            // Array notation
2646.
                            a[i] = a[i].replace(__reArray, '');
2647.
    
2648.
                            // Condition allows simply [] to be passed in
2649.
                            if ( a[i] !== "" ) {
2650.
                                data = data[ a[i] ];
2651.
                            }
2652.
                            out = [];
2653.
    
2654.
                            // Get the remainder of the nested object to get
2655.
                            a.splice( 0, i+1 );
2656.
                            innerSrc = a.join('.');
2657.
    
2658.
                            // Traverse each entry in the array getting the properties requested
2659.
                            if ( $.isArray( data ) ) {
2660.
                                for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
2661.
                                    out.push( fetchData( data[j], type, innerSrc ) );
2662.
                                }
2663.
                            }
2664.
    
2665.
                            // If a string is given in between the array notation indicators, that
2666.
                            // is used to join the strings together, otherwise an array is returned
2667.
                            var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
2668.
                            data = (join==="") ? out : out.join(join);
2669.
    
2670.
                            // The inner call to fetchData has already traversed through the remainder
2671.
                            // of the source requested, so we exit from the loop
2672.
                            break;
2673.
                        }
2674.
                        else if ( funcNotation )
2675.
                        {
2676.
                            // Function call
2677.
                            a[i] = a[i].replace(__reFn, '');
2678.
                            data = data[ a[i] ]();
2679.
                            continue;
2680.
                        }
2681.
    
2682.
                        if ( data === null || data[ a[i] ] === undefined )
2683.
                        {
2684.
                            return undefined;
2685.
                        }
2686.
                        data = data[ a[i] ];
2687.
                    }
2688.
                }
2689.
    
2690.
                return data;
2691.
            };
2692.
    
2693.
            return function (data, type) { // row and meta also passed, but not used
2694.
                return fetchData( data, type, mSource );
2695.
            };
2696.
        }
2697.
        else
2698.
        {
2699.
            /* Array or flat object mapping */
2700.
            return function (data, type) { // row and meta also passed, but not used
2701.
                return data[mSource];
2702.
            };
2703.
        }
2704.
    }
2705.
    
2706.
    
2707.
    /**
2708.
     * Return a function that can be used to set data from a source object, taking
2709.
     * into account the ability to use nested objects as a source
2710.
     *  @param {string|int|function} mSource The data source for the object
2711.
     *  @returns {function} Data set function
2712.
     *  @memberof DataTable#oApi
2713.
     */
2714.
    function _fnSetObjectDataFn( mSource )
2715.
    {
2716.
        if ( $.isPlainObject( mSource ) )
2717.
        {
2718.
            /* Unlike get, only the underscore (global) option is used for for
2719.
             * setting data since we don't know the type here. This is why an object
2720.
             * option is not documented for `mData` (which is read/write), but it is
2721.
             * for `mRender` which is read only.
2722.
             */
2723.
            return _fnSetObjectDataFn( mSource._ );
2724.
        }
2725.
        else if ( mSource === null )
2726.
        {
2727.
            /* Nothing to do when the data source is null */
2728.
            return function () {};
2729.
        }
2730.
        else if ( typeof mSource === 'function' )
2731.
        {
2732.
            return function (data, val, meta) {
2733.
                mSource( data, 'set', val, meta );
2734.
            };
2735.
        }
2736.
        else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2737.
                  mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2738.
        {
2739.
            /* Like the get, we need to get data from a nested object */
2740.
            var setData = function (data, val, src) {
2741.
                var a = _fnSplitObjNotation( src ), b;
2742.
                var aLast = a[a.length-1];
2743.
                var arrayNotation, funcNotation, o, innerSrc;
2744.
    
2745.
                for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
2746.
                {
2747.
                    // Check if we are dealing with an array notation request
2748.
                    arrayNotation = a[i].match(__reArray);
2749.
                    funcNotation = a[i].match(__reFn);
2750.
    
2751.
                    if ( arrayNotation )
2752.
                    {
2753.
                        a[i] = a[i].replace(__reArray, '');
2754.
                        data[ a[i] ] = [];
2755.
    
2756.
                        // Get the remainder of the nested object to set so we can recurse
2757.
                        b = a.slice();
2758.
                        b.splice( 0, i+1 );
2759.
                        innerSrc = b.join('.');
2760.
    
2761.
                        // Traverse each entry in the array setting the properties requested
2762.
                        if ( $.isArray( val ) )
2763.
                        {
2764.
                            for ( var j=0, jLen=val.length ; j<jLen ; j++ )
2765.
                            {
2766.
                                o = {};
2767.
                                setData( o, val[j], innerSrc );
2768.
                                data[ a[i] ].push( o );
2769.
                            }
2770.
                        }
2771.
                        else
2772.
                        {
2773.
                            // We've been asked to save data to an array, but it
2774.
                            // isn't array data to be saved. Best that can be done
2775.
                            // is to just save the value.
2776.
                            data[ a[i] ] = val;
2777.
                        }
2778.
    
2779.
                        // The inner call to setData has already traversed through the remainder
2780.
                        // of the source and has set the data, thus we can exit here
2781.
                        return;
2782.
                    }
2783.
                    else if ( funcNotation )
2784.
                    {
2785.
                        // Function call
2786.
                        a[i] = a[i].replace(__reFn, '');
2787.
                        data = data[ a[i] ]( val );
2788.
                    }
2789.
    
2790.
                    // If the nested object doesn't currently exist - since we are
2791.
                    // trying to set the value - create it
2792.
                    if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
2793.
                    {
2794.
                        data[ a[i] ] = {};
2795.
                    }
2796.
                    data = data[ a[i] ];
2797.
                }
2798.
    
2799.
                // Last item in the input - i.e, the actual set
2800.
                if ( aLast.match(__reFn ) )
2801.
                {
2802.
                    // Function call
2803.
                    data = data[ aLast.replace(__reFn, '') ]( val );
2804.
                }
2805.
                else
2806.
                {
2807.
                    // If array notation is used, we just want to strip it and use the property name
2808.
                    // and assign the value. If it isn't used, then we get the result we want anyway
2809.
                    data[ aLast.replace(__reArray, '') ] = val;
2810.
                }
2811.
            };
2812.
    
2813.
            return function (data, val) { // meta is also passed in, but not used
2814.
                return setData( data, val, mSource );
2815.
            };
2816.
        }
2817.
        else
2818.
        {
2819.
            /* Array or flat object mapping */
2820.
            return function (data, val) { // meta is also passed in, but not used
2821.
                data[mSource] = val;
2822.
            };
2823.
        }
2824.
    }
2825.
    
2826.
    
2827.
    /**
2828.
     * Return an array with the full table data
2829.
     *  @param {object} oSettings dataTables settings object
2830.
     *  @returns array {array} aData Master data array
2831.
     *  @memberof DataTable#oApi
2832.
     */
2833.
    function _fnGetDataMaster ( settings )
2834.
    {
2835.
        return _pluck( settings.aoData, '_aData' );
2836.
    }
2837.
    
2838.
    
2839.
    /**
2840.
     * Nuke the table
2841.
     *  @param {object} oSettings dataTables settings object
2842.
     *  @memberof DataTable#oApi
2843.
     */
2844.
    function _fnClearTable( settings )
2845.
    {
2846.
        settings.aoData.length = 0;
2847.
        settings.aiDisplayMaster.length = 0;
2848.
        settings.aiDisplay.length = 0;
2849.
        settings.aIds = {};
2850.
    }
2851.
    
2852.
    
2853.
     /**
2854.
     * Take an array of integers (index array) and remove a target integer (value - not
2855.
     * the key!)
2856.
     *  @param {array} a Index array to target
2857.
     *  @param {int} iTarget value to find
2858.
     *  @memberof DataTable#oApi
2859.
     */
2860.
    function _fnDeleteIndex( a, iTarget, splice )
2861.
    {
2862.
        var iTargetIndex = -1;
2863.
    
2864.
        for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2865.
        {
2866.
            if ( a[i] == iTarget )
2867.
            {
2868.
                iTargetIndex = i;
2869.
            }
2870.
            else if ( a[i] > iTarget )
2871.
            {
2872.
                a[i]--;
2873.
            }
2874.
        }
2875.
    
2876.
        if ( iTargetIndex != -1 && splice === undefined )
2877.
        {
2878.
            a.splice( iTargetIndex, 1 );
2879.
        }
2880.
    }
2881.
    
2882.
    
2883.
    /**
2884.
     * Mark cached data as invalid such that a re-read of the data will occur when
2885.
     * the cached data is next requested. Also update from the data source object.
2886.
     *
2887.
     * @param {object} settings DataTables settings object
2888.
     * @param {int}    rowIdx   Row index to invalidate
2889.
     * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
2890.
     *     or 'data'
2891.
     * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
2892.
     *     row will be invalidated
2893.
     * @memberof DataTable#oApi
2894.
     *
2895.
     * @todo For the modularisation of v1.11 this will need to become a callback, so
2896.
     *   the sort and filter methods can subscribe to it. That will required
2897.
     *   initialisation options for sorting, which is why it is not already baked in
2898.
     */
2899.
    function _fnInvalidate( settings, rowIdx, src, colIdx )
2900.
    {
2901.
        var row = settings.aoData[ rowIdx ];
2902.
        var i, ien;
2903.
        var cellWrite = function ( cell, col ) {
2904.
            // This is very frustrating, but in IE if you just write directly
2905.
            // to innerHTML, and elements that are overwritten are GC'ed,
2906.
            // even if there is a reference to them elsewhere
2907.
            while ( cell.childNodes.length ) {
2908.
                cell.removeChild( cell.firstChild );
2909.
            }
2910.
    
2911.
            cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
2912.
        };
2913.
    
2914.
        // Are we reading last data from DOM or the data object?
2915.
        if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
2916.
            // Read the data from the DOM
2917.
            row._aData = _fnGetRowElements(
2918.
                    settings, row, colIdx, colIdx === undefined ? undefined : row._aData
2919.
                )
2920.
                .data;
2921.
        }
2922.
        else {
2923.
            // Reading from data object, update the DOM
2924.
            var cells = row.anCells;
2925.
    
2926.
            if ( cells ) {
2927.
                if ( colIdx !== undefined ) {
2928.
                    cellWrite( cells[colIdx], colIdx );
2929.
                }
2930.
                else {
2931.
                    for ( i=0, ien=cells.length ; i<ien ; i++ ) {
2932.
                        cellWrite( cells[i], i );
2933.
                    }
2934.
                }
2935.
            }
2936.
        }
2937.
    
2938.
        // For both row and cell invalidation, the cached data for sorting and
2939.
        // filtering is nulled out
2940.
        row._aSortData = null;
2941.
        row._aFilterData = null;
2942.
    
2943.
        // Invalidate the type for a specific column (if given) or all columns since
2944.
        // the data might have changed
2945.
        var cols = settings.aoColumns;
2946.
        if ( colIdx !== undefined ) {
2947.
            cols[ colIdx ].sType = null;
2948.
        }
2949.
        else {
2950.
            for ( i=0, ien=cols.length ; i<ien ; i++ ) {
2951.
                cols[i].sType = null;
2952.
            }
2953.
    
2954.
            // Update DataTables special `DT_*` attributes for the row
2955.
            _fnRowAttributes( settings, row );
2956.
        }
2957.
    }
2958.
    
2959.
    
2960.
    /**
2961.
     * Build a data source object from an HTML row, reading the contents of the
2962.
     * cells that are in the row.
2963.
     *
2964.
     * @param {object} settings DataTables settings object
2965.
     * @param {node|object} TR element from which to read data or existing row
2966.
     *   object from which to re-read the data from the cells
2967.
     * @param {int} [colIdx] Optional column index
2968.
     * @param {array|object} [d] Data source object. If `colIdx` is given then this
2969.
     *   parameter should also be given and will be used to write the data into.
2970.
     *   Only the column in question will be written
2971.
     * @returns {object} Object with two parameters: `data` the data read, in
2972.
     *   document order, and `cells` and array of nodes (they can be useful to the
2973.
     *   caller, so rather than needing a second traversal to get them, just return
2974.
     *   them from here).
2975.
     * @memberof DataTable#oApi
2976.
     */
2977.
    function _fnGetRowElements( settings, row, colIdx, d )
2978.
    {
2979.
        var
2980.
            tds = [],
2981.
            td = row.firstChild,
2982.
            name, col, o, i=0, contents,
2983.
            columns = settings.aoColumns,
2984.
            objectRead = settings._rowReadObject;
2985.
    
2986.
        // Allow the data object to be passed in, or construct
2987.
        d = d !== undefined ?
2988.
            d :
2989.
            objectRead ?
2990.
                {} :
2991.
                [];
2992.
    
2993.
        var attr = function ( str, td  ) {
2994.
            if ( typeof str === 'string' ) {
2995.
                var idx = str.indexOf('@');
2996.
    
2997.
                if ( idx !== -1 ) {
2998.
                    var attr = str.substring( idx+1 );
2999.
                    var setter = _fnSetObjectDataFn( str );
3000.
                    setter( d, td.getAttribute( attr ) );
3001.
                }
3002.
            }
3003.
        };
3004.
    
3005.
        // Read data from a cell and store into the data object
3006.
        var cellProcess = function ( cell ) {
3007.
            if ( colIdx === undefined || colIdx === i ) {
3008.
                col = columns[i];
3009.
                contents = $.trim(cell.innerHTML);
3010.
    
3011.
                if ( col && col._bAttrSrc ) {
3012.
                    var setter = _fnSetObjectDataFn( col.mData._ );
3013.
                    setter( d, contents );
3014.
    
3015.
                    attr( col.mData.sort, cell );
3016.
                    attr( col.mData.type, cell );
3017.
                    attr( col.mData.filter, cell );
3018.
                }
3019.
                else {
3020.
                    // Depending on the `data` option for the columns the data can
3021.
                    // be read to either an object or an array.
3022.
                    if ( objectRead ) {
3023.
                        if ( ! col._setter ) {
3024.
                            // Cache the setter function
3025.
                            col._setter = _fnSetObjectDataFn( col.mData );
3026.
                        }
3027.
                        col._setter( d, contents );
3028.
                    }
3029.
                    else {
3030.
                        d[i] = contents;
3031.
                    }
3032.
                }
3033.
            }
3034.
    
3035.
            i++;
3036.
        };
3037.
    
3038.
        if ( td ) {
3039.
            // `tr` element was passed in
3040.
            while ( td ) {
3041.
                name = td.nodeName.toUpperCase();
3042.
    
3043.
                if ( name == "TD" || name == "TH" ) {
3044.
                    cellProcess( td );
3045.
                    tds.push( td );
3046.
                }
3047.
    
3048.
                td = td.nextSibling;
3049.
            }
3050.
        }
3051.
        else {
3052.
            // Existing row object passed in
3053.
            tds = row.anCells;
3054.
    
3055.
            for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
3056.
                cellProcess( tds[j] );
3057.
            }
3058.
        }
3059.
    
3060.
        // Read the ID from the DOM if present
3061.
        var rowNode = row.firstChild ? row : row.nTr;
3062.
    
3063.
        if ( rowNode ) {
3064.
            var id = rowNode.getAttribute( 'id' );
3065.
    
3066.
            if ( id ) {
3067.
                _fnSetObjectDataFn( settings.rowId )( d, id );
3068.
            }
3069.
        }
3070.
    
3071.
        return {
3072.
            data: d,
3073.
            cells: tds
3074.
        };
3075.
    }
3076.
    /**
3077.
     * Create a new TR element (and it's TD children) for a row
3078.
     *  @param {object} oSettings dataTables settings object
3079.
     *  @param {int} iRow Row to consider
3080.
     *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
3081.
     *    DataTables will create a row automatically
3082.
     *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
3083.
     *    if nTr is.
3084.
     *  @memberof DataTable#oApi
3085.
     */
3086.
    function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
3087.
    {
3088.
        var
3089.
            row = oSettings.aoData[iRow],
3090.
            rowData = row._aData,
3091.
            cells = [],
3092.
            nTr, nTd, oCol,
3093.
            i, iLen, create;
3094.
    
3095.
        if ( row.nTr === null )
3096.
        {
3097.
            nTr = nTrIn || document.createElement('tr');
3098.
    
3099.
            row.nTr = nTr;
3100.
            row.anCells = cells;
3101.
    
3102.
            /* Use a private property on the node to allow reserve mapping from the node
3103.
             * to the aoData array for fast look up
3104.
             */
3105.
            nTr._DT_RowIndex = iRow;
3106.
    
3107.
            /* Special parameters can be given by the data source to be used on the row */
3108.
            _fnRowAttributes( oSettings, row );
3109.
    
3110.
            /* Process each column */
3111.
            for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
3112.
            {
3113.
                oCol = oSettings.aoColumns[i];
3114.
                create = nTrIn ? false : true;
3115.
    
3116.
                nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
3117.
                nTd._DT_CellIndex = {
3118.
                    row: iRow,
3119.
                    column: i
3120.
                };
3121.
                
3122.
                cells.push( nTd );
3123.
    
3124.
                // Need to create the HTML if new, or if a rendering function is defined
3125.
                if ( create || ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
3126.
                     (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
3127.
                )) {
3128.
                    nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
3129.
                }
3130.
    
3131.
                /* Add user defined class */
3132.
                if ( oCol.sClass )
3133.
                {
3134.
                    nTd.className += ' '+oCol.sClass;
3135.
                }
3136.
    
3137.
                // Visibility - add or remove as required
3138.
                if ( oCol.bVisible && ! nTrIn )
3139.
                {
3140.
                    nTr.appendChild( nTd );
3141.
                }
3142.
                else if ( ! oCol.bVisible && nTrIn )
3143.
                {
3144.
                    nTd.parentNode.removeChild( nTd );
3145.
                }
3146.
    
3147.
                if ( oCol.fnCreatedCell )
3148.
                {
3149.
                    oCol.fnCreatedCell.call( oSettings.oInstance,
3150.
                        nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
3151.
                    );
3152.
                }
3153.
            }
3154.
    
3155.
            _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
3156.
        }
3157.
    
3158.
        // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
3159.
        // and deployed
3160.
        row.nTr.setAttribute( 'role', 'row' );
3161.
    }
3162.
    
3163.
    
3164.
    /**
3165.
     * Add attributes to a row based on the special `DT_*` parameters in a data
3166.
     * source object.
3167.
     *  @param {object} settings DataTables settings object
3168.
     *  @param {object} DataTables row object for the row to be modified
3169.
     *  @memberof DataTable#oApi
3170.
     */
3171.
    function _fnRowAttributes( settings, row )
3172.
    {
3173.
        var tr = row.nTr;
3174.
        var data = row._aData;
3175.
    
3176.
        if ( tr ) {
3177.
            var id = settings.rowIdFn( data );
3178.
    
3179.
            if ( id ) {
3180.
                tr.id = id;
3181.
            }
3182.
    
3183.
            if ( data.DT_RowClass ) {
3184.
                // Remove any classes added by DT_RowClass before
3185.
                var a = data.DT_RowClass.split(' ');
3186.
                row.__rowc = row.__rowc ?
3187.
                    _unique( row.__rowc.concat( a ) ) :
3188.
                    a;
3189.
    
3190.
                $(tr)
3191.
                    .removeClass( row.__rowc.join(' ') )
3192.
                    .addClass( data.DT_RowClass );
3193.
            }
3194.
    
3195.
            if ( data.DT_RowAttr ) {
3196.
                $(tr).attr( data.DT_RowAttr );
3197.
            }
3198.
    
3199.
            if ( data.DT_RowData ) {
3200.
                $(tr).data( data.DT_RowData );
3201.
            }
3202.
        }
3203.
    }
3204.
    
3205.
    
3206.
    /**
3207.
     * Create the HTML header for the table
3208.
     *  @param {object} oSettings dataTables settings object
3209.
     *  @memberof DataTable#oApi
3210.
     */
3211.
    function _fnBuildHead( oSettings )
3212.
    {
3213.
        var i, ien, cell, row, column;
3214.
        var thead = oSettings.nTHead;
3215.
        var tfoot = oSettings.nTFoot;
3216.
        var createHeader = $('th, td', thead).length === 0;
3217.
        var classes = oSettings.oClasses;
3218.
        var columns = oSettings.aoColumns;
3219.
    
3220.
        if ( createHeader ) {
3221.
            row = $('<tr/>').appendTo( thead );
3222.
        }
3223.
    
3224.
        for ( i=0, ien=columns.length ; i<ien ; i++ ) {
3225.
            column = columns[i];
3226.
            cell = $( column.nTh ).addClass( column.sClass );
3227.
    
3228.
            if ( createHeader ) {
3229.
                cell.appendTo( row );
3230.
            }
3231.
    
3232.
            // 1.11 move into sorting
3233.
            if ( oSettings.oFeatures.bSort ) {
3234.
                cell.addClass( column.sSortingClass );
3235.
    
3236.
                if ( column.bSortable !== false ) {
3237.
                    cell
3238.
                        .attr( 'tabindex', oSettings.iTabIndex )
3239.
                        .attr( 'aria-controls', oSettings.sTableId );
3240.
    
3241.
                    _fnSortAttachListener( oSettings, column.nTh, i );
3242.
                }
3243.
            }
3244.
    
3245.
            if ( column.sTitle != cell[0].innerHTML ) {
3246.
                cell.html( column.sTitle );
3247.
            }
3248.
    
3249.
            _fnRenderer( oSettings, 'header' )(
3250.
                oSettings, cell, column, classes
3251.
            );
3252.
        }
3253.
    
3254.
        if ( createHeader ) {
3255.
            _fnDetectHeader( oSettings.aoHeader, thead );
3256.
        }
3257.
        
3258.
        /* ARIA role for the rows */
3259.
         $(thead).find('>tr').attr('role', 'row');
3260.
    
3261.
        /* Deal with the footer - add classes if required */
3262.
        $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
3263.
        $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
3264.
    
3265.
        // Cache the footer cells. Note that we only take the cells from the first
3266.
        // row in the footer. If there is more than one row the user wants to
3267.
        // interact with, they need to use the table().foot() method. Note also this
3268.
        // allows cells to be used for multiple columns using colspan
3269.
        if ( tfoot !== null ) {
3270.
            var cells = oSettings.aoFooter[0];
3271.
    
3272.
            for ( i=0, ien=cells.length ; i<ien ; i++ ) {
3273.
                column = columns[i];
3274.
                column.nTf = cells[i].cell;
3275.
    
3276.
                if ( column.sClass ) {
3277.
                    $(column.nTf).addClass( column.sClass );
3278.
                }
3279.
            }
3280.
        }
3281.
    }
3282.
    
3283.
    
3284.
    /**
3285.
     * Draw the header (or footer) element based on the column visibility states. The
3286.
     * methodology here is to use the layout array from _fnDetectHeader, modified for
3287.
     * the instantaneous column visibility, to construct the new layout. The grid is
3288.
     * traversed over cell at a time in a rows x columns grid fashion, although each
3289.
     * cell insert can cover multiple elements in the grid - which is tracks using the
3290.
     * aApplied array. Cell inserts in the grid will only occur where there isn't
3291.
     * already a cell in that position.
3292.
     *  @param {object} oSettings dataTables settings object
3293.
     *  @param array {objects} aoSource Layout array from _fnDetectHeader
3294.
     *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
3295.
     *  @memberof DataTable#oApi
3296.
     */
3297.
    function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
3298.
    {
3299.
        var i, iLen, j, jLen, k, kLen, n, nLocalTr;
3300.
        var aoLocal = [];
3301.
        var aApplied = [];
3302.
        var iColumns = oSettings.aoColumns.length;
3303.
        var iRowspan, iColspan;
3304.
    
3305.
        if ( ! aoSource )
3306.
        {
3307.
            return;
3308.
        }
3309.
    
3310.
        if (  bIncludeHidden === undefined )
3311.
        {
3312.
            bIncludeHidden = false;
3313.
        }
3314.
    
3315.
        /* Make a copy of the master layout array, but without the visible columns in it */
3316.
        for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
3317.
        {
3318.
            aoLocal[i] = aoSource[i].slice();
3319.
            aoLocal[i].nTr = aoSource[i].nTr;
3320.
    
3321.
            /* Remove any columns which are currently hidden */
3322.
            for ( j=iColumns-1 ; j>=0 ; j-- )
3323.
            {
3324.
                if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
3325.
                {
3326.
                    aoLocal[i].splice( j, 1 );
3327.
                }
3328.
            }
3329.
    
3330.
            /* Prep the applied array - it needs an element for each row */
3331.
            aApplied.push( [] );
3332.
        }
3333.
    
3334.
        for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
3335.
        {
3336.
            nLocalTr = aoLocal[i].nTr;
3337.
    
3338.
            /* All cells are going to be replaced, so empty out the row */
3339.
            if ( nLocalTr )
3340.
            {
3341.
                while( (n = nLocalTr.firstChild) )
3342.
                {
3343.
                    nLocalTr.removeChild( n );
3344.
                }
3345.
            }
3346.
    
3347.
            for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
3348.
            {
3349.
                iRowspan = 1;
3350.
                iColspan = 1;
3351.
    
3352.
                /* Check to see if there is already a cell (row/colspan) covering our target
3353.
                 * insert point. If there is, then there is nothing to do.
3354.
                 */
3355.
                if ( aApplied[i][j] === undefined )
3356.
                {
3357.
                    nLocalTr.appendChild( aoLocal[i][j].cell );
3358.
                    aApplied[i][j] = 1;
3359.
    
3360.
                    /* Expand the cell to cover as many rows as needed */
3361.
                    while ( aoLocal[i+iRowspan] !== undefined &&
3362.
                            aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
3363.
                    {
3364.
                        aApplied[i+iRowspan][j] = 1;
3365.
                        iRowspan++;
3366.
                    }
3367.
    
3368.
                    /* Expand the cell to cover as many columns as needed */
3369.
                    while ( aoLocal[i][j+iColspan] !== undefined &&
3370.
                            aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
3371.
                    {
3372.
                        /* Must update the applied array over the rows for the columns */
3373.
                        for ( k=0 ; k<iRowspan ; k++ )
3374.
                        {
3375.
                            aApplied[i+k][j+iColspan] = 1;
3376.
                        }
3377.
                        iColspan++;
3378.
                    }
3379.
    
3380.
                    /* Do the actual expansion in the DOM */
3381.
                    $(aoLocal[i][j].cell)
3382.
                        .attr('rowspan', iRowspan)
3383.
                        .attr('colspan', iColspan);
3384.
                }
3385.
            }
3386.
        }
3387.
    }
3388.
    
3389.
    
3390.
    /**
3391.
     * Insert the required TR nodes into the table for display
3392.
     *  @param {object} oSettings dataTables settings object
3393.
     *  @memberof DataTable#oApi
3394.
     */
3395.
    function _fnDraw( oSettings )
3396.
    {
3397.
        /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
3398.
        var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
3399.
        if ( $.inArray( false, aPreDraw ) !== -1 )
3400.
        {
3401.
            _fnProcessingDisplay( oSettings, false );
3402.
            return;
3403.
        }
3404.
    
3405.
        var i, iLen, n;
3406.
        var anRows = [];
3407.
        var iRowCount = 0;
3408.
        var asStripeClasses = oSettings.asStripeClasses;
3409.
        var iStripes = asStripeClasses.length;
3410.
        var iOpenRows = oSettings.aoOpenRows.length;
3411.
        var oLang = oSettings.oLanguage;
3412.
        var iInitDisplayStart = oSettings.iInitDisplayStart;
3413.
        var bServerSide = _fnDataSource( oSettings ) == 'ssp';
3414.
        var aiDisplay = oSettings.aiDisplay;
3415.
    
3416.
        oSettings.bDrawing = true;
3417.
    
3418.
        /* Check and see if we have an initial draw position from state saving */
3419.
        if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
3420.
        {
3421.
            oSettings._iDisplayStart = bServerSide ?
3422.
                iInitDisplayStart :
3423.
                iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
3424.
                    0 :
3425.
                    iInitDisplayStart;
3426.
    
3427.
            oSettings.iInitDisplayStart = -1;
3428.
        }
3429.
    
3430.
        var iDisplayStart = oSettings._iDisplayStart;
3431.
        var iDisplayEnd = oSettings.fnDisplayEnd();
3432.
    
3433.
        /* Server-side processing draw intercept */
3434.
        if ( oSettings.bDeferLoading )
3435.
        {
3436.
            oSettings.bDeferLoading = false;
3437.
            oSettings.iDraw++;
3438.
            _fnProcessingDisplay( oSettings, false );
3439.
        }
3440.
        else if ( !bServerSide )
3441.
        {
3442.
            oSettings.iDraw++;
3443.
        }
3444.
        else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
3445.
        {
3446.
            return;
3447.
        }
3448.
    
3449.
        if ( aiDisplay.length !== 0 )
3450.
        {
3451.
            var iStart = bServerSide ? 0 : iDisplayStart;
3452.
            var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
3453.
    
3454.
            for ( var j=iStart ; j<iEnd ; j++ )
3455.
            {
3456.
                var iDataIndex = aiDisplay[j];
3457.
                var aoData = oSettings.aoData[ iDataIndex ];
3458.
                if ( aoData.nTr === null )
3459.
                {
3460.
                    _fnCreateTr( oSettings, iDataIndex );
3461.
                }
3462.
    
3463.
                var nRow = aoData.nTr;
3464.
    
3465.
                /* Remove the old striping classes and then add the new one */
3466.
                if ( iStripes !== 0 )
3467.
                {
3468.
                    var sStripe = asStripeClasses[ iRowCount % iStripes ];
3469.
                    if ( aoData._sRowStripe != sStripe )
3470.
                    {
3471.
                        $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
3472.
                        aoData._sRowStripe = sStripe;
3473.
                    }
3474.
                }
3475.
    
3476.
                // Row callback functions - might want to manipulate the row
3477.
                // iRowCount and j are not currently documented. Are they at all
3478.
                // useful?
3479.
                _fnCallbackFire( oSettings, 'aoRowCallback', null,
3480.
                    [nRow, aoData._aData, iRowCount, j, iDataIndex] );
3481.
    
3482.
                anRows.push( nRow );
3483.
                iRowCount++;
3484.
            }
3485.
        }
3486.
        else
3487.
        {
3488.
            /* Table is empty - create a row with an empty message in it */
3489.
            var sZero = oLang.sZeroRecords;
3490.
            if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
3491.
            {
3492.
                sZero = oLang.sLoadingRecords;
3493.
            }
3494.
            else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
3495.
            {
3496.
                sZero = oLang.sEmptyTable;
3497.
            }
3498.
    
3499.
            anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
3500.
                .append( $('<td />', {
3501.
                    'valign':  'top',
3502.
                    'colSpan': _fnVisbleColumns( oSettings ),
3503.
                    'class':   oSettings.oClasses.sRowEmpty
3504.
                } ).html( sZero ) )[0];
3505.
        }
3506.
    
3507.
        /* Header and footer callbacks */
3508.
        _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
3509.
            _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3510.
    
3511.
        _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
3512.
            _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3513.
    
3514.
        var body = $(oSettings.nTBody);
3515.
    
3516.
        body.children().detach();
3517.
        body.append( $(anRows) );
3518.
    
3519.
        /* Call all required callback functions for the end of a draw */
3520.
        _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
3521.
    
3522.
        /* Draw is complete, sorting and filtering must be as well */
3523.
        oSettings.bSorted = false;
3524.
        oSettings.bFiltered = false;
3525.
        oSettings.bDrawing = false;
3526.
    }
3527.
    
3528.
    
3529.
    /**
3530.
     * Redraw the table - taking account of the various features which are enabled
3531.
     *  @param {object} oSettings dataTables settings object
3532.
     *  @param {boolean} [holdPosition] Keep the current paging position. By default
3533.
     *    the paging is reset to the first page
3534.
     *  @memberof DataTable#oApi
3535.
     */
3536.
    function _fnReDraw( settings, holdPosition )
3537.
    {
3538.
        var
3539.
            features = settings.oFeatures,
3540.
            sort     = features.bSort,
3541.
            filter   = features.bFilter;
3542.
    
3543.
        if ( sort ) {
3544.
            _fnSort( settings );
3545.
        }
3546.
    
3547.
        if ( filter ) {
3548.
            _fnFilterComplete( settings, settings.oPreviousSearch );
3549.
        }
3550.
        else {
3551.
            // No filtering, so we want to just use the display master
3552.
            settings.aiDisplay = settings.aiDisplayMaster.slice();
3553.
        }
3554.
    
3555.
        if ( holdPosition !== true ) {
3556.
            settings._iDisplayStart = 0;
3557.
        }
3558.
    
3559.
        // Let any modules know about the draw hold position state (used by
3560.
        // scrolling internally)
3561.
        settings._drawHold = holdPosition;
3562.
    
3563.
        _fnDraw( settings );
3564.
    
3565.
        settings._drawHold = false;
3566.
    }
3567.
    
3568.
    
3569.
    /**
3570.
     * Add the options to the page HTML for the table
3571.
     *  @param {object} oSettings dataTables settings object
3572.
     *  @memberof DataTable#oApi
3573.
     */
3574.
    function _fnAddOptionsHtml ( oSettings )
3575.
    {
3576.
        var classes = oSettings.oClasses;
3577.
        var table = $(oSettings.nTable);
3578.
        var holding = $('<div/>').insertBefore( table ); // Holding element for speed
3579.
        var features = oSettings.oFeatures;
3580.
    
3581.
        // All DataTables are wrapped in a div
3582.
        var insert = $('<div/>', {
3583.
            id:      oSettings.sTableId+'_wrapper',
3584.
            'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
3585.
        } );
3586.
    
3587.
        oSettings.nHolding = holding[0];
3588.
        oSettings.nTableWrapper = insert[0];
3589.
        oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
3590.
    
3591.
        /* Loop over the user set positioning and place the elements as needed */
3592.
        var aDom = oSettings.sDom.split('');
3593.
        var featureNode, cOption, nNewNode, cNext, sAttr, j;
3594.
        for ( var i=0 ; i<aDom.length ; i++ )
3595.
        {
3596.
            featureNode = null;
3597.
            cOption = aDom[i];
3598.
    
3599.
            if ( cOption == '<' )
3600.
            {
3601.
                /* New container div */
3602.
                nNewNode = $('<div/>')[0];
3603.
    
3604.
                /* Check to see if we should append an id and/or a class name to the container */
3605.
                cNext = aDom[i+1];
3606.
                if ( cNext == "'" || cNext == '"' )
3607.
                {
3608.
                    sAttr = "";
3609.
                    j = 2;
3610.
                    while ( aDom[i+j] != cNext )
3611.
                    {
3612.
                        sAttr += aDom[i+j];
3613.
                        j++;
3614.
                    }
3615.
    
3616.
                    /* Replace jQuery UI constants @todo depreciated */
3617.
                    if ( sAttr == "H" )
3618.
                    {
3619.
                        sAttr = classes.sJUIHeader;
3620.
                    }
3621.
                    else if ( sAttr == "F" )
3622.
                    {
3623.
                        sAttr = classes.sJUIFooter;
3624.
                    }
3625.
    
3626.
                    /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
3627.
                     * breaks the string into parts and applies them as needed
3628.
                     */
3629.
                    if ( sAttr.indexOf('.') != -1 )
3630.
                    {
3631.
                        var aSplit = sAttr.split('.');
3632.
                        nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
3633.
                        nNewNode.className = aSplit[1];
3634.
                    }
3635.
                    else if ( sAttr.charAt(0) == "#" )
3636.
                    {
3637.
                        nNewNode.id = sAttr.substr(1, sAttr.length-1);
3638.
                    }
3639.
                    else
3640.
                    {
3641.
                        nNewNode.className = sAttr;
3642.
                    }
3643.
    
3644.
                    i += j; /* Move along the position array */
3645.
                }
3646.
    
3647.
                insert.append( nNewNode );
3648.
                insert = $(nNewNode);
3649.
            }
3650.
            else if ( cOption == '>' )
3651.
            {
3652.
                /* End container div */
3653.
                insert = insert.parent();
3654.
            }
3655.
            // @todo Move options into their own plugins?
3656.
            else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
3657.
            {
3658.
                /* Length */
3659.
                featureNode = _fnFeatureHtmlLength( oSettings );
3660.
            }
3661.
            else if ( cOption == 'f' && features.bFilter )
3662.
            {
3663.
                /* Filter */
3664.
                featureNode = _fnFeatureHtmlFilter( oSettings );
3665.
            }
3666.
            else if ( cOption == 'r' && features.bProcessing )
3667.
            {
3668.
                /* pRocessing */
3669.
                featureNode = _fnFeatureHtmlProcessing( oSettings );
3670.
            }
3671.
            else if ( cOption == 't' )
3672.
            {
3673.
                /* Table */
3674.
                featureNode = _fnFeatureHtmlTable( oSettings );
3675.
            }
3676.
            else if ( cOption ==  'i' && features.bInfo )
3677.
            {
3678.
                /* Info */
3679.
                featureNode = _fnFeatureHtmlInfo( oSettings );
3680.
            }
3681.
            else if ( cOption == 'p' && features.bPaginate )
3682.
            {
3683.
                /* Pagination */
3684.
                featureNode = _fnFeatureHtmlPaginate( oSettings );
3685.
            }
3686.
            else if ( DataTable.ext.feature.length !== 0 )
3687.
            {
3688.
                /* Plug-in features */
3689.
                var aoFeatures = DataTable.ext.feature;
3690.
                for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
3691.
                {
3692.
                    if ( cOption == aoFeatures[k].cFeature )
3693.
                    {
3694.
                        featureNode = aoFeatures[k].fnInit( oSettings );
3695.
                        break;
3696.
                    }
3697.
                }
3698.
            }
3699.
    
3700.
            /* Add to the 2D features array */
3701.
            if ( featureNode )
3702.
            {
3703.
                var aanFeatures = oSettings.aanFeatures;
3704.
    
3705.
                if ( ! aanFeatures[cOption] )
3706.
                {
3707.
                    aanFeatures[cOption] = [];
3708.
                }
3709.
    
3710.
                aanFeatures[cOption].push( featureNode );
3711.
                insert.append( featureNode );
3712.
            }
3713.
        }
3714.
    
3715.
        /* Built our DOM structure - replace the holding div with what we want */
3716.
        holding.replaceWith( insert );
3717.
        oSettings.nHolding = null;
3718.
    }
3719.
    
3720.
    
3721.
    /**
3722.
     * Use the DOM source to create up an array of header cells. The idea here is to
3723.
     * create a layout grid (array) of rows x columns, which contains a reference
3724.
     * to the cell that that point in the grid (regardless of col/rowspan), such that
3725.
     * any column / row could be removed and the new grid constructed
3726.
     *  @param array {object} aLayout Array to store the calculated layout in
3727.
     *  @param {node} nThead The header/footer element for the table
3728.
     *  @memberof DataTable#oApi
3729.
     */
3730.
    function _fnDetectHeader ( aLayout, nThead )
3731.
    {
3732.
        var nTrs = $(nThead).children('tr');
3733.
        var nTr, nCell;
3734.
        var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
3735.
        var bUnique;
3736.
        var fnShiftCol = function ( a, i, j ) {
3737.
            var k = a[i];
3738.
                    while ( k[j] ) {
3739.
                j++;
3740.
            }
3741.
            return j;
3742.
        };
3743.
    
3744.
        aLayout.splice( 0, aLayout.length );
3745.
    
3746.
        /* We know how many rows there are in the layout - so prep it */
3747.
        for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3748.
        {
3749.
            aLayout.push( [] );
3750.
        }
3751.
    
3752.
        /* Calculate a layout array */
3753.
        for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3754.
        {
3755.
            nTr = nTrs[i];
3756.
            iColumn = 0;
3757.
    
3758.
            /* For every cell in the row... */
3759.
            nCell = nTr.firstChild;
3760.
            while ( nCell ) {
3761.
                if ( nCell.nodeName.toUpperCase() == "TD" ||
3762.
                     nCell.nodeName.toUpperCase() == "TH" )
3763.
                {
3764.
                    /* Get the col and rowspan attributes from the DOM and sanitise them */
3765.
                    iColspan = nCell.getAttribute('colspan') * 1;
3766.
                    iRowspan = nCell.getAttribute('rowspan') * 1;
3767.
                    iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
3768.
                    iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
3769.
    
3770.
                    /* There might be colspan cells already in this row, so shift our target
3771.
                     * accordingly
3772.
                     */
3773.
                    iColShifted = fnShiftCol( aLayout, i, iColumn );
3774.
    
3775.
                    /* Cache calculation for unique columns */
3776.
                    bUnique = iColspan === 1 ? true : false;
3777.
    
3778.
                    /* If there is col / rowspan, copy the information into the layout grid */
3779.
                    for ( l=0 ; l<iColspan ; l++ )
3780.
                    {
3781.
                        for ( k=0 ; k<iRowspan ; k++ )
3782.
                        {
3783.
                            aLayout[i+k][iColShifted+l] = {
3784.
                                "cell": nCell,
3785.
                                "unique": bUnique
3786.
                            };
3787.
                            aLayout[i+k].nTr = nTr;
3788.
                        }
3789.
                    }
3790.
                }
3791.
                nCell = nCell.nextSibling;
3792.
            }
3793.
        }
3794.
    }
3795.
    
3796.
    
3797.
    /**
3798.
     * Get an array of unique th elements, one for each column
3799.
     *  @param {object} oSettings dataTables settings object
3800.
     *  @param {node} nHeader automatically detect the layout from this node - optional
3801.
     *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
3802.
     *  @returns array {node} aReturn list of unique th's
3803.
     *  @memberof DataTable#oApi
3804.
     */
3805.
    function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
3806.
    {
3807.
        var aReturn = [];
3808.
        if ( !aLayout )
3809.
        {
3810.
            aLayout = oSettings.aoHeader;
3811.
            if ( nHeader )
3812.
            {
3813.
                aLayout = [];
3814.
                _fnDetectHeader( aLayout, nHeader );
3815.
            }
3816.
        }
3817.
    
3818.
        for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
3819.
        {
3820.
            for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
3821.
            {
3822.
                if ( aLayout[i][j].unique &&
3823.
                     (!aReturn[j] || !oSettings.bSortCellsTop) )
3824.
                {
3825.
                    aReturn[j] = aLayout[i][j].cell;
3826.
                }
3827.
            }
3828.
        }
3829.
    
3830.
        return aReturn;
3831.
    }
3832.
    
3833.
    /**
3834.
     * Create an Ajax call based on the table's settings, taking into account that
3835.
     * parameters can have multiple forms, and backwards compatibility.
3836.
     *
3837.
     * @param {object} oSettings dataTables settings object
3838.
     * @param {array} data Data to send to the server, required by
3839.
     *     DataTables - may be augmented by developer callbacks
3840.
     * @param {function} fn Callback function to run when data is obtained
3841.
     */
3842.
    function _fnBuildAjax( oSettings, data, fn )
3843.
    {
3844.
        // Compatibility with 1.9-, allow fnServerData and event to manipulate
3845.
        _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
3846.
    
3847.
        // Convert to object based for 1.10+ if using the old array scheme which can
3848.
        // come from server-side processing or serverParams
3849.
        if ( data && $.isArray(data) ) {
3850.
            var tmp = {};
3851.
            var rbracket = /(.*?)\[\]$/;
3852.
    
3853.
            $.each( data, function (key, val) {
3854.
                var match = val.name.match(rbracket);
3855.
    
3856.
                if ( match ) {
3857.
                    // Support for arrays
3858.
                    var name = match[0];
3859.
    
3860.
                    if ( ! tmp[ name ] ) {
3861.
                        tmp[ name ] = [];
3862.
                    }
3863.
                    tmp[ name ].push( val.value );
3864.
                }
3865.
                else {
3866.
                    tmp[val.name] = val.value;
3867.
                }
3868.
            } );
3869.
            data = tmp;
3870.
        }
3871.
    
3872.
        var ajaxData;
3873.
        var ajax = oSettings.ajax;
3874.
        var instance = oSettings.oInstance;
3875.
        var callback = function ( json ) {
3876.
            _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
3877.
            fn( json );
3878.
        };
3879.
    
3880.
        if ( $.isPlainObject( ajax ) && ajax.data )
3881.
        {
3882.
            ajaxData = ajax.data;
3883.
    
3884.
            var newData = typeof ajaxData === 'function' ?
3885.
                ajaxData( data, oSettings ) :  // fn can manipulate data or return
3886.
                ajaxData;                      // an object object or array to merge
3887.
    
3888.
            // If the function returned something, use that alone
3889.
            data = typeof ajaxData === 'function' && newData ?
3890.
                newData :
3891.
                $.extend( true, data, newData );
3892.
    
3893.
            // Remove the data property as we've resolved it already and don't want
3894.
            // jQuery to do it again (it is restored at the end of the function)
3895.
            delete ajax.data;
3896.
        }
3897.
    
3898.
        var baseAjax = {
3899.
            "data": data,
3900.
            "success": function (json) {
3901.
                var error = json.error || json.sError;
3902.
                if ( error ) {
3903.
                    _fnLog( oSettings, 0, error );
3904.
                }
3905.
    
3906.
                oSettings.json = json;
3907.
                callback( json );
3908.
            },
3909.
            "dataType": "json",
3910.
            "cache": false,
3911.
            "type": oSettings.sServerMethod,
3912.
            "error": function (xhr, error, thrown) {
3913.
                var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
3914.
    
3915.
                if ( $.inArray( true, ret ) === -1 ) {
3916.
                    if ( error == "parsererror" ) {
3917.
                        _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
3918.
                    }
3919.
                    else if ( xhr.readyState === 4 ) {
3920.
                        _fnLog( oSettings, 0, 'Ajax error', 7 );
3921.
                    }
3922.
                }
3923.
    
3924.
                _fnProcessingDisplay( oSettings, false );
3925.
            }
3926.
        };
3927.
    
3928.
        // Store the data submitted for the API
3929.
        oSettings.oAjaxData = data;
3930.
    
3931.
        // Allow plug-ins and external processes to modify the data
3932.
        _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
3933.
    
3934.
        if ( oSettings.fnServerData )
3935.
        {
3936.
            // DataTables 1.9- compatibility
3937.
            oSettings.fnServerData.call( instance,
3938.
                oSettings.sAjaxSource,
3939.
                $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
3940.
                    return { name: key, value: val };
3941.
                } ),
3942.
                callback,
3943.
                oSettings
3944.
            );
3945.
        }
3946.
        else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
3947.
        {
3948.
            // DataTables 1.9- compatibility
3949.
            oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
3950.
                url: ajax || oSettings.sAjaxSource
3951.
            } ) );
3952.
        }
3953.
        else if ( typeof ajax === 'function' )
3954.
        {
3955.
            // Is a function - let the caller define what needs to be done
3956.
            oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
3957.
        }
3958.
        else
3959.
        {
3960.
            // Object to extend the base settings
3961.
            oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
3962.
    
3963.
            // Restore for next time around
3964.
            ajax.data = ajaxData;
3965.
        }
3966.
    }
3967.
    
3968.
    
3969.
    /**
3970.
     * Update the table using an Ajax call
3971.
     *  @param {object} settings dataTables settings object
3972.
     *  @returns {boolean} Block the table drawing or not
3973.
     *  @memberof DataTable#oApi
3974.
     */
3975.
    function _fnAjaxUpdate( settings )
3976.
    {
3977.
        if ( settings.bAjaxDataGet ) {
3978.
            settings.iDraw++;
3979.
            _fnProcessingDisplay( settings, true );
3980.
    
3981.
            _fnBuildAjax(
3982.
                settings,
3983.
                _fnAjaxParameters( settings ),
3984.
                function(json) {
3985.
                    _fnAjaxUpdateDraw( settings, json );
3986.
                }
3987.
            );
3988.
    
3989.
            return false;
3990.
        }
3991.
        return true;
3992.
    }
3993.
    
3994.
    
3995.
    /**
3996.
     * Build up the parameters in an object needed for a server-side processing
3997.
     * request. Note that this is basically done twice, is different ways - a modern
3998.
     * method which is used by default in DataTables 1.10 which uses objects and
3999.
     * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
4000.
     * the sAjaxSource option is used in the initialisation, or the legacyAjax
4001.
     * option is set.
4002.
     *  @param {object} oSettings dataTables settings object
4003.
     *  @returns {bool} block the table drawing or not
4004.
     *  @memberof DataTable#oApi
4005.
     */
4006.
    function _fnAjaxParameters( settings )
4007.
    {
4008.
        var
4009.
            columns = settings.aoColumns,
4010.
            columnCount = columns.length,
4011.
            features = settings.oFeatures,
4012.
            preSearch = settings.oPreviousSearch,
4013.
            preColSearch = settings.aoPreSearchCols,
4014.
            i, data = [], dataProp, column, columnSearch,
4015.
            sort = _fnSortFlatten( settings ),
4016.
            displayStart = settings._iDisplayStart,
4017.
            displayLength = features.bPaginate !== false ?
4018.
                settings._iDisplayLength :
4019.
                -1;
4020.
    
4021.
        var param = function ( name, value ) {
4022.
            data.push( { 'name': name, 'value': value } );
4023.
        };
4024.
    
4025.
        // DataTables 1.9- compatible method
4026.
        param( 'sEcho',          settings.iDraw );
4027.
        param( 'iColumns',       columnCount );
4028.
        param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
4029.
        param( 'iDisplayStart',  displayStart );
4030.
        param( 'iDisplayLength', displayLength );
4031.
    
4032.
        // DataTables 1.10+ method
4033.
        var d = {
4034.
            draw:    settings.iDraw,
4035.
            columns: [],
4036.
            order:   [],
4037.
            start:   displayStart,
4038.
            length:  displayLength,
4039.
            search:  {
4040.
                value: preSearch.sSearch,
4041.
                regex: preSearch.bRegex
4042.
            }
4043.
        };
4044.
    
4045.
        for ( i=0 ; i<columnCount ; i++ ) {
4046.
            column = columns[i];
4047.
            columnSearch = preColSearch[i];
4048.
            dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
4049.
    
4050.
            d.columns.push( {
4051.
                data:       dataProp,
4052.
                name:       column.sName,
4053.
                searchable: column.bSearchable,
4054.
                orderable:  column.bSortable,
4055.
                search:     {
4056.
                    value: columnSearch.sSearch,
4057.
                    regex: columnSearch.bRegex
4058.
                }
4059.
            } );
4060.
    
4061.
            param( "mDataProp_"+i, dataProp );
4062.
    
4063.
            if ( features.bFilter ) {
4064.
                param( 'sSearch_'+i,     columnSearch.sSearch );
4065.
                param( 'bRegex_'+i,      columnSearch.bRegex );
4066.
                param( 'bSearchable_'+i, column.bSearchable );
4067.
            }
4068.
    
4069.
            if ( features.bSort ) {
4070.
                param( 'bSortable_'+i, column.bSortable );
4071.
            }
4072.
        }
4073.
    
4074.
        if ( features.bFilter ) {
4075.
            param( 'sSearch', preSearch.sSearch );
4076.
            param( 'bRegex', preSearch.bRegex );
4077.
        }
4078.
    
4079.
        if ( features.bSort ) {
4080.
            $.each( sort, function ( i, val ) {
4081.
                d.order.push( { column: val.col, dir: val.dir } );
4082.
    
4083.
                param( 'iSortCol_'+i, val.col );
4084.
                param( 'sSortDir_'+i, val.dir );
4085.
            } );
4086.
    
4087.
            param( 'iSortingCols', sort.length );
4088.
        }
4089.
    
4090.
        // If the legacy.ajax parameter is null, then we automatically decide which
4091.
        // form to use, based on sAjaxSource
4092.
        var legacy = DataTable.ext.legacy.ajax;
4093.
        if ( legacy === null ) {
4094.
            return settings.sAjaxSource ? data : d;
4095.
        }
4096.
    
4097.
        // Otherwise, if legacy has been specified then we use that to decide on the
4098.
        // form
4099.
        return legacy ? data : d;
4100.
    }
4101.
    
4102.
    
4103.
    /**
4104.
     * Data the data from the server (nuking the old) and redraw the table
4105.
     *  @param {object} oSettings dataTables settings object
4106.
     *  @param {object} json json data return from the server.
4107.
     *  @param {string} json.sEcho Tracking flag for DataTables to match requests
4108.
     *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
4109.
     *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
4110.
     *  @param {array} json.aaData The data to display on this page
4111.
     *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
4112.
     *  @memberof DataTable#oApi
4113.
     */
4114.
    function _fnAjaxUpdateDraw ( settings, json )
4115.
    {
4116.
        // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
4117.
        // Support both
4118.
        var compat = function ( old, modern ) {
4119.
            return json[old] !== undefined ? json[old] : json[modern];
4120.
        };
4121.
    
4122.
        var data = _fnAjaxDataSrc( settings, json );
4123.
        var draw            = compat( 'sEcho',                'draw' );
4124.
        var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
4125.
        var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
4126.
    
4127.
        if ( draw !== undefined ) {
4128.
            // Protect against out of sequence returns
4129.
            if ( draw*1 < settings.iDraw ) {
4130.
                return;
4131.
            }
4132.
            settings.iDraw = draw * 1;
4133.
        }
4134.
    
4135.
        _fnClearTable( settings );
4136.
        settings._iRecordsTotal   = parseInt(recordsTotal, 10);
4137.
        settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
4138.
    
4139.
        for ( var i=0, ien=data.length ; i<ien ; i++ ) {
4140.
            _fnAddData( settings, data[i] );
4141.
        }
4142.
        settings.aiDisplay = settings.aiDisplayMaster.slice();
4143.
    
4144.
        settings.bAjaxDataGet = false;
4145.
        _fnDraw( settings );
4146.
    
4147.
        if ( ! settings._bInitComplete ) {
4148.
            _fnInitComplete( settings, json );
4149.
        }
4150.
    
4151.
        settings.bAjaxDataGet = true;
4152.
        _fnProcessingDisplay( settings, false );
4153.
    }
4154.
    
4155.
    
4156.
    /**
4157.
     * Get the data from the JSON data source to use for drawing a table. Using
4158.
     * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
4159.
     * source object, or from a processing function.
4160.
     *  @param {object} oSettings dataTables settings object
4161.
     *  @param  {object} json Data source object / array from the server
4162.
     *  @return {array} Array of data to use
4163.
     */
4164.
    function _fnAjaxDataSrc ( oSettings, json )
4165.
    {
4166.
        var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
4167.
            oSettings.ajax.dataSrc :
4168.
            oSettings.sAjaxDataProp; // Compatibility with 1.9-.
4169.
    
4170.
        // Compatibility with 1.9-. In order to read from aaData, check if the
4171.
        // default has been changed, if not, check for aaData
4172.
        if ( dataSrc === 'data' ) {
4173.
            return json.aaData || json[dataSrc];
4174.
        }
4175.
    
4176.
        return dataSrc !== "" ?
4177.
            _fnGetObjectDataFn( dataSrc )( json ) :
4178.
            json;
4179.
    }
4180.
    
4181.
    /**
4182.
     * Generate the node required for filtering text
4183.
     *  @returns {node} Filter control element
4184.
     *  @param {object} oSettings dataTables settings object
4185.
     *  @memberof DataTable#oApi
4186.
     */
4187.
    function _fnFeatureHtmlFilter ( settings )
4188.
    {
4189.
        var classes = settings.oClasses;
4190.
        var tableId = settings.sTableId;
4191.
        var language = settings.oLanguage;
4192.
        var previousSearch = settings.oPreviousSearch;
4193.
        var features = settings.aanFeatures;
4194.
        var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
4195.
    
4196.
        var str = language.sSearch;
4197.
        str = str.match(/_INPUT_/) ?
4198.
            str.replace('_INPUT_', input) :
4199.
            str+input;
4200.
    
4201.
        var filter = $('<div/>', {
4202.
                'id': ! features.f ? tableId+'_filter' : null,
4203.
                'class': classes.sFilter
4204.
            } )
4205.
            .append( $('<label/>' ).append( str ) );
4206.
    
4207.
        var searchFn = function() {
4208.
            /* Update all other filter input elements for the new display */
4209.
            var n = features.f;
4210.
            var val = !this.value ? "" : this.value; // mental IE8 fix :-(
4211.
    
4212.
            /* Now do the filter */
4213.
            if ( val != previousSearch.sSearch ) {
4214.
                _fnFilterComplete( settings, {
4215.
                    "sSearch": val,
4216.
                    "bRegex": previousSearch.bRegex,
4217.
                    "bSmart": previousSearch.bSmart ,
4218.
                    "bCaseInsensitive": previousSearch.bCaseInsensitive
4219.
                } );
4220.
    
4221.
                // Need to redraw, without resorting
4222.
                settings._iDisplayStart = 0;
4223.
                _fnDraw( settings );
4224.
            }
4225.
        };
4226.
    
4227.
        var searchDelay = settings.searchDelay !== null ?
4228.
            settings.searchDelay :
4229.
            _fnDataSource( settings ) === 'ssp' ?
4230.
                400 :
4231.
                0;
4232.
    
4233.
        var jqFilter = $('input', filter)
4234.
            .val( previousSearch.sSearch )
4235.
            .attr( 'placeholder', language.sSearchPlaceholder )
4236.
            .on(
4237.
                'keyup.DT search.DT input.DT paste.DT cut.DT',
4238.
                searchDelay ?
4239.
                    _fnThrottle( searchFn, searchDelay ) :
4240.
                    searchFn
4241.
            )
4242.
            .on( 'mouseup', function(e) {
4243.
                // Edge fix! Edge 17 does not trigger anything other than mouse events when clicking
4244.
                // on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`
4245.
                // checks the value to see if it has changed. In other browsers it won't have.
4246.
                setTimeout( function () {
4247.
                    searchFn.call(jqFilter[0]);
4248.
                }, 10);
4249.
            } )
4250.
            .on( 'keypress.DT', function(e) {
4251.
                /* Prevent form submission */
4252.
                if ( e.keyCode == 13 ) {
4253.
                    return false;
4254.
                }
4255.
            } )
4256.
            .attr('aria-controls', tableId);
4257.
    
4258.
        // Update the input elements whenever the table is filtered
4259.
        $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
4260.
            if ( settings === s ) {
4261.
                // IE9 throws an 'unknown error' if document.activeElement is used
4262.
                // inside an iframe or frame...
4263.
                try {
4264.
                    if ( jqFilter[0] !== document.activeElement ) {
4265.
                        jqFilter.val( previousSearch.sSearch );
4266.
                    }
4267.
                }
4268.
                catch ( e ) {}
4269.
            }
4270.
        } );
4271.
    
4272.
        return filter[0];
4273.
    }
4274.
    
4275.
    
4276.
    /**
4277.
     * Filter the table using both the global filter and column based filtering
4278.
     *  @param {object} oSettings dataTables settings object
4279.
     *  @param {object} oSearch search information
4280.
     *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
4281.
     *  @memberof DataTable#oApi
4282.
     */
4283.
    function _fnFilterComplete ( oSettings, oInput, iForce )
4284.
    {
4285.
        var oPrevSearch = oSettings.oPreviousSearch;
4286.
        var aoPrevSearch = oSettings.aoPreSearchCols;
4287.
        var fnSaveFilter = function ( oFilter ) {
4288.
            /* Save the filtering values */
4289.
            oPrevSearch.sSearch = oFilter.sSearch;
4290.
            oPrevSearch.bRegex = oFilter.bRegex;
4291.
            oPrevSearch.bSmart = oFilter.bSmart;
4292.
            oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
4293.
        };
4294.
        var fnRegex = function ( o ) {
4295.
            // Backwards compatibility with the bEscapeRegex option
4296.
            return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
4297.
        };
4298.
    
4299.
        // Resolve any column types that are unknown due to addition or invalidation
4300.
        // @todo As per sort - can this be moved into an event handler?
4301.
        _fnColumnTypes( oSettings );
4302.
    
4303.
        /* In server-side processing all filtering is done by the server, so no point hanging around here */
4304.
        if ( _fnDataSource( oSettings ) != 'ssp' )
4305.
        {
4306.
            /* Global filter */
4307.
            _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
4308.
            fnSaveFilter( oInput );
4309.
    
4310.
            /* Now do the individual column filter */
4311.
            for ( var i=0 ; i<aoPrevSearch.length ; i++ )
4312.
            {
4313.
                _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
4314.
                    aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
4315.
            }
4316.
    
4317.
            /* Custom filtering */
4318.
            _fnFilterCustom( oSettings );
4319.
        }
4320.
        else
4321.
        {
4322.
            fnSaveFilter( oInput );
4323.
        }
4324.
    
4325.
        /* Tell the draw function we have been filtering */
4326.
        oSettings.bFiltered = true;
4327.
        _fnCallbackFire( oSettings, null, 'search', [oSettings] );
4328.
    }
4329.
    
4330.
    
4331.
    /**
4332.
     * Apply custom filtering functions
4333.
     *  @param {object} oSettings dataTables settings object
4334.
     *  @memberof DataTable#oApi
4335.
     */
4336.
    function _fnFilterCustom( settings )
4337.
    {
4338.
        var filters = DataTable.ext.search;
4339.
        var displayRows = settings.aiDisplay;
4340.
        var row, rowIdx;
4341.
    
4342.
        for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
4343.
            var rows = [];
4344.
    
4345.
            // Loop over each row and see if it should be included
4346.
            for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
4347.
                rowIdx = displayRows[ j ];
4348.
                row = settings.aoData[ rowIdx ];
4349.
    
4350.
                if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
4351.
                    rows.push( rowIdx );
4352.
                }
4353.
            }
4354.
    
4355.
            // So the array reference doesn't break set the results into the
4356.
            // existing array
4357.
            displayRows.length = 0;
4358.
            $.merge( displayRows, rows );
4359.
        }
4360.
    }
4361.
    
4362.
    
4363.
    /**
4364.
     * Filter the table on a per-column basis
4365.
     *  @param {object} oSettings dataTables settings object
4366.
     *  @param {string} sInput string to filter on
4367.
     *  @param {int} iColumn column to filter
4368.
     *  @param {bool} bRegex treat search string as a regular expression or not
4369.
     *  @param {bool} bSmart use smart filtering or not
4370.
     *  @param {bool} bCaseInsensitive Do case insenstive matching or not
4371.
     *  @memberof DataTable#oApi
4372.
     */
4373.
    function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
4374.
    {
4375.
        if ( searchStr === '' ) {
4376.
            return;
4377.
        }
4378.
    
4379.
        var data;
4380.
        var out = [];
4381.
        var display = settings.aiDisplay;
4382.
        var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
4383.
    
4384.
        for ( var i=0 ; i<display.length ; i++ ) {
4385.
            data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4386.
    
4387.
            if ( rpSearch.test( data ) ) {
4388.
                out.push( display[i] );
4389.
            }
4390.
        }
4391.
    
4392.
        settings.aiDisplay = out;
4393.
    }
4394.
    
4395.
    
4396.
    /**
4397.
     * Filter the data table based on user input and draw the table
4398.
     *  @param {object} settings dataTables settings object
4399.
     *  @param {string} input string to filter on
4400.
     *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
4401.
     *  @param {bool} regex treat as a regular expression or not
4402.
     *  @param {bool} smart perform smart filtering or not
4403.
     *  @param {bool} caseInsensitive Do case insenstive matching or not
4404.
     *  @memberof DataTable#oApi
4405.
     */
4406.
    function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
4407.
    {
4408.
        var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
4409.
        var prevSearch = settings.oPreviousSearch.sSearch;
4410.
        var displayMaster = settings.aiDisplayMaster;
4411.
        var display, invalidated, i;
4412.
        var filtered = [];
4413.
    
4414.
        // Need to take account of custom filtering functions - always filter
4415.
        if ( DataTable.ext.search.length !== 0 ) {
4416.
            force = true;
4417.
        }
4418.
    
4419.
        // Check if any of the rows were invalidated
4420.
        invalidated = _fnFilterData( settings );
4421.
    
4422.
        // If the input is blank - we just want the full data set
4423.
        if ( input.length <= 0 ) {
4424.
            settings.aiDisplay = displayMaster.slice();
4425.
        }
4426.
        else {
4427.
            // New search - start from the master array
4428.
            if ( invalidated ||
4429.
                 force ||
4430.
                 regex ||
4431.
                 prevSearch.length > input.length ||
4432.
                 input.indexOf(prevSearch) !== 0 ||
4433.
                 settings.bSorted // On resort, the display master needs to be
4434.
                                  // re-filtered since indexes will have changed
4435.
            ) {
4436.
                settings.aiDisplay = displayMaster.slice();
4437.
            }
4438.
    
4439.
            // Search the display array
4440.
            display = settings.aiDisplay;
4441.
    
4442.
            for ( i=0 ; i<display.length ; i++ ) {
4443.
                if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
4444.
                    filtered.push( display[i] );
4445.
                }
4446.
            }
4447.
    
4448.
            settings.aiDisplay = filtered;
4449.
        }
4450.
    }
4451.
    
4452.
    
4453.
    /**
4454.
     * Build a regular expression object suitable for searching a table
4455.
     *  @param {string} sSearch string to search for
4456.
     *  @param {bool} bRegex treat as a regular expression or not
4457.
     *  @param {bool} bSmart perform smart filtering or not
4458.
     *  @param {bool} bCaseInsensitive Do case insensitive matching or not
4459.
     *  @returns {RegExp} constructed object
4460.
     *  @memberof DataTable#oApi
4461.
     */
4462.
    function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
4463.
    {
4464.
        search = regex ?
4465.
            search :
4466.
            _fnEscapeRegex( search );
4467.
        
4468.
        if ( smart ) {
4469.
            /* For smart filtering we want to allow the search to work regardless of
4470.
             * word order. We also want double quoted text to be preserved, so word
4471.
             * order is important - a la google. So this is what we want to
4472.
             * generate:
4473.
             * 
4474.
             * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
4475.
             */
4476.
            var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
4477.
                if ( word.charAt(0) === '"' ) {
4478.
                    var m = word.match( /^"(.*)"$/ );
4479.
                    word = m ? m[1] : word;
4480.
                }
4481.
    
4482.
                return word.replace('"', '');
4483.
            } );
4484.
    
4485.
            search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
4486.
        }
4487.
    
4488.
        return new RegExp( search, caseInsensitive ? 'i' : '' );
4489.
    }
4490.
    
4491.
    
4492.
    /**
4493.
     * Escape a string such that it can be used in a regular expression
4494.
     *  @param {string} sVal string to escape
4495.
     *  @returns {string} escaped string
4496.
     *  @memberof DataTable#oApi
4497.
     */
4498.
    var _fnEscapeRegex = DataTable.util.escapeRegex;
4499.
    
4500.
    var __filter_div = $('<div>')[0];
4501.
    var __filter_div_textContent = __filter_div.textContent !== undefined;
4502.
    
4503.
    // Update the filtering data for each row if needed (by invalidation or first run)
4504.
    function _fnFilterData ( settings )
4505.
    {
4506.
        var columns = settings.aoColumns;
4507.
        var column;
4508.
        var i, j, ien, jen, filterData, cellData, row;
4509.
        var fomatters = DataTable.ext.type.search;
4510.
        var wasInvalidated = false;
4511.
    
4512.
        for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4513.
            row = settings.aoData[i];
4514.
    
4515.
            if ( ! row._aFilterData ) {
4516.
                filterData = [];
4517.
    
4518.
                for ( j=0, jen=columns.length ; j<jen ; j++ ) {
4519.
                    column = columns[j];
4520.
    
4521.
                    if ( column.bSearchable ) {
4522.
                        cellData = _fnGetCellData( settings, i, j, 'filter' );
4523.
    
4524.
                        if ( fomatters[ column.sType ] ) {
4525.
                            cellData = fomatters[ column.sType ]( cellData );
4526.
                        }
4527.
    
4528.
                        // Search in DataTables 1.10 is string based. In 1.11 this
4529.
                        // should be altered to also allow strict type checking.
4530.
                        if ( cellData === null ) {
4531.
                            cellData = '';
4532.
                        }
4533.
    
4534.
                        if ( typeof cellData !== 'string' && cellData.toString ) {
4535.
                            cellData = cellData.toString();
4536.
                        }
4537.
                    }
4538.
                    else {
4539.
                        cellData = '';
4540.
                    }
4541.
    
4542.
                    // If it looks like there is an HTML entity in the string,
4543.
                    // attempt to decode it so sorting works as expected. Note that
4544.
                    // we could use a single line of jQuery to do this, but the DOM
4545.
                    // method used here is much faster http://jsperf.com/html-decode
4546.
                    if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
4547.
                        __filter_div.innerHTML = cellData;
4548.
                        cellData = __filter_div_textContent ?
4549.
                            __filter_div.textContent :
4550.
                            __filter_div.innerText;
4551.
                    }
4552.
    
4553.
                    if ( cellData.replace ) {
4554.
                        cellData = cellData.replace(/[\r\n\u2028]/g, '');
4555.
                    }
4556.
    
4557.
                    filterData.push( cellData );
4558.
                }
4559.
    
4560.
                row._aFilterData = filterData;
4561.
                row._sFilterRow = filterData.join('  ');
4562.
                wasInvalidated = true;
4563.
            }
4564.
        }
4565.
    
4566.
        return wasInvalidated;
4567.
    }
4568.
    
4569.
    
4570.
    /**
4571.
     * Convert from the internal Hungarian notation to camelCase for external
4572.
     * interaction
4573.
     *  @param {object} obj Object to convert
4574.
     *  @returns {object} Inverted object
4575.
     *  @memberof DataTable#oApi
4576.
     */
4577.
    function _fnSearchToCamel ( obj )
4578.
    {
4579.
        return {
4580.
            search:          obj.sSearch,
4581.
            smart:           obj.bSmart,
4582.
            regex:           obj.bRegex,
4583.
            caseInsensitive: obj.bCaseInsensitive
4584.
        };
4585.
    }
4586.
    
4587.
    
4588.
    
4589.
    /**
4590.
     * Convert from camelCase notation to the internal Hungarian. We could use the
4591.
     * Hungarian convert function here, but this is cleaner
4592.
     *  @param {object} obj Object to convert
4593.
     *  @returns {object} Inverted object
4594.
     *  @memberof DataTable#oApi
4595.
     */
4596.
    function _fnSearchToHung ( obj )
4597.
    {
4598.
        return {
4599.
            sSearch:          obj.search,
4600.
            bSmart:           obj.smart,
4601.
            bRegex:           obj.regex,
4602.
            bCaseInsensitive: obj.caseInsensitive
4603.
        };
4604.
    }
4605.
    
4606.
    /**
4607.
     * Generate the node required for the info display
4608.
     *  @param {object} oSettings dataTables settings object
4609.
     *  @returns {node} Information element
4610.
     *  @memberof DataTable#oApi
4611.
     */
4612.
    function _fnFeatureHtmlInfo ( settings )
4613.
    {
4614.
        var
4615.
            tid = settings.sTableId,
4616.
            nodes = settings.aanFeatures.i,
4617.
            n = $('<div/>', {
4618.
                'class': settings.oClasses.sInfo,
4619.
                'id': ! nodes ? tid+'_info' : null
4620.
            } );
4621.
    
4622.
        if ( ! nodes ) {
4623.
            // Update display on each draw
4624.
            settings.aoDrawCallback.push( {
4625.
                "fn": _fnUpdateInfo,
4626.
                "sName": "information"
4627.
            } );
4628.
    
4629.
            n
4630.
                .attr( 'role', 'status' )
4631.
                .attr( 'aria-live', 'polite' );
4632.
    
4633.
            // Table is described by our info div
4634.
            $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
4635.
        }
4636.
    
4637.
        return n[0];
4638.
    }
4639.
    
4640.
    
4641.
    /**
4642.
     * Update the information elements in the display
4643.
     *  @param {object} settings dataTables settings object
4644.
     *  @memberof DataTable#oApi
4645.
     */
4646.
    function _fnUpdateInfo ( settings )
4647.
    {
4648.
        /* Show information about the table */
4649.
        var nodes = settings.aanFeatures.i;
4650.
        if ( nodes.length === 0 ) {
4651.
            return;
4652.
        }
4653.
    
4654.
        var
4655.
            lang  = settings.oLanguage,
4656.
            start = settings._iDisplayStart+1,
4657.
            end   = settings.fnDisplayEnd(),
4658.
            max   = settings.fnRecordsTotal(),
4659.
            total = settings.fnRecordsDisplay(),
4660.
            out   = total ?
4661.
                lang.sInfo :
4662.
                lang.sInfoEmpty;
4663.
    
4664.
        if ( total !== max ) {
4665.
            /* Record set after filtering */
4666.
            out += ' ' + lang.sInfoFiltered;
4667.
        }
4668.
    
4669.
        // Convert the macros
4670.
        out += lang.sInfoPostFix;
4671.
        out = _fnInfoMacros( settings, out );
4672.
    
4673.
        var callback = lang.fnInfoCallback;
4674.
        if ( callback !== null ) {
4675.
            out = callback.call( settings.oInstance,
4676.
                settings, start, end, max, total, out
4677.
            );
4678.
        }
4679.
    
4680.
        $(nodes).html( out );
4681.
    }
4682.
    
4683.
    
4684.
    function _fnInfoMacros ( settings, str )
4685.
    {
4686.
        // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
4687.
        // internally
4688.
        var
4689.
            formatter  = settings.fnFormatNumber,
4690.
            start      = settings._iDisplayStart+1,
4691.
            len        = settings._iDisplayLength,
4692.
            vis        = settings.fnRecordsDisplay(),
4693.
            all        = len === -1;
4694.
    
4695.
        return str.
4696.
            replace(/_START_/g, formatter.call( settings, start ) ).
4697.
            replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
4698.
            replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
4699.
            replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
4700.
            replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
4701.
            replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
4702.
    }
4703.
    
4704.
    
4705.
    
4706.
    /**
4707.
     * Draw the table for the first time, adding all required features
4708.
     *  @param {object} settings dataTables settings object
4709.
     *  @memberof DataTable#oApi
4710.
     */
4711.
    function _fnInitialise ( settings )
4712.
    {
4713.
        var i, iLen, iAjaxStart=settings.iInitDisplayStart;
4714.
        var columns = settings.aoColumns, column;
4715.
        var features = settings.oFeatures;
4716.
        var deferLoading = settings.bDeferLoading; // value modified by the draw
4717.
    
4718.
        /* Ensure that the table data is fully initialised */
4719.
        if ( ! settings.bInitialised ) {
4720.
            setTimeout( function(){ _fnInitialise( settings ); }, 200 );
4721.
            return;
4722.
        }
4723.
    
4724.
        /* Show the display HTML options */
4725.
        _fnAddOptionsHtml( settings );
4726.
    
4727.
        /* Build and draw the header / footer for the table */
4728.
        _fnBuildHead( settings );
4729.
        _fnDrawHead( settings, settings.aoHeader );
4730.
        _fnDrawHead( settings, settings.aoFooter );
4731.
    
4732.
        /* Okay to show that something is going on now */
4733.
        _fnProcessingDisplay( settings, true );
4734.
    
4735.
        /* Calculate sizes for columns */
4736.
        if ( features.bAutoWidth ) {
4737.
            _fnCalculateColumnWidths( settings );
4738.
        }
4739.
    
4740.
        for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
4741.
            column = columns[i];
4742.
    
4743.
            if ( column.sWidth ) {
4744.
                column.nTh.style.width = _fnStringToCss( column.sWidth );
4745.
            }
4746.
        }
4747.
    
4748.
        _fnCallbackFire( settings, null, 'preInit', [settings] );
4749.
    
4750.
        // If there is default sorting required - let's do it. The sort function
4751.
        // will do the drawing for us. Otherwise we draw the table regardless of the
4752.
        // Ajax source - this allows the table to look initialised for Ajax sourcing
4753.
        // data (show 'loading' message possibly)
4754.
        _fnReDraw( settings );
4755.
    
4756.
        // Server-side processing init complete is done by _fnAjaxUpdateDraw
4757.
        var dataSrc = _fnDataSource( settings );
4758.
        if ( dataSrc != 'ssp' || deferLoading ) {
4759.
            // if there is an ajax source load the data
4760.
            if ( dataSrc == 'ajax' ) {
4761.
                _fnBuildAjax( settings, [], function(json) {
4762.
                    var aData = _fnAjaxDataSrc( settings, json );
4763.
    
4764.
                    // Got the data - add it to the table
4765.
                    for ( i=0 ; i<aData.length ; i++ ) {
4766.
                        _fnAddData( settings, aData[i] );
4767.
                    }
4768.
    
4769.
                    // Reset the init display for cookie saving. We've already done
4770.
                    // a filter, and therefore cleared it before. So we need to make
4771.
                    // it appear 'fresh'
4772.
                    settings.iInitDisplayStart = iAjaxStart;
4773.
    
4774.
                    _fnReDraw( settings );
4775.
    
4776.
                    _fnProcessingDisplay( settings, false );
4777.
                    _fnInitComplete( settings, json );
4778.
                }, settings );
4779.
            }
4780.
            else {
4781.
                _fnProcessingDisplay( settings, false );
4782.
                _fnInitComplete( settings );
4783.
            }
4784.
        }
4785.
    }
4786.
    
4787.
    
4788.
    /**
4789.
     * Draw the table for the first time, adding all required features
4790.
     *  @param {object} oSettings dataTables settings object
4791.
     *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
4792.
     *    with client-side processing (optional)
4793.
     *  @memberof DataTable#oApi
4794.
     */
4795.
    function _fnInitComplete ( settings, json )
4796.
    {
4797.
        settings._bInitComplete = true;
4798.
    
4799.
        // When data was added after the initialisation (data or Ajax) we need to
4800.
        // calculate the column sizing
4801.
        if ( json || settings.oInit.aaData ) {
4802.
            _fnAdjustColumnSizing( settings );
4803.
        }
4804.
    
4805.
        _fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
4806.
        _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
4807.
    }
4808.
    
4809.
    
4810.
    function _fnLengthChange ( settings, val )
4811.
    {
4812.
        var len = parseInt( val, 10 );
4813.
        settings._iDisplayLength = len;
4814.
    
4815.
        _fnLengthOverflow( settings );
4816.
    
4817.
        // Fire length change event
4818.
        _fnCallbackFire( settings, null, 'length', [settings, len] );
4819.
    }
4820.
    
4821.
    
4822.
    /**
4823.
     * Generate the node required for user display length changing
4824.
     *  @param {object} settings dataTables settings object
4825.
     *  @returns {node} Display length feature node
4826.
     *  @memberof DataTable#oApi
4827.
     */
4828.
    function _fnFeatureHtmlLength ( settings )
4829.
    {
4830.
        var
4831.
            classes  = settings.oClasses,
4832.
            tableId  = settings.sTableId,
4833.
            menu     = settings.aLengthMenu,
4834.
            d2       = $.isArray( menu[0] ),
4835.
            lengths  = d2 ? menu[0] : menu,
4836.
            language = d2 ? menu[1] : menu;
4837.
    
4838.
        var select = $('<select/>', {
4839.
            'name':          tableId+'_length',
4840.
            'aria-controls': tableId,
4841.
            'class':         classes.sLengthSelect
4842.
        } );
4843.
    
4844.
        for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
4845.
            select[0][ i ] = new Option(
4846.
                typeof language[i] === 'number' ?
4847.
                    settings.fnFormatNumber( language[i] ) :
4848.
                    language[i],
4849.
                lengths[i]
4850.
            );
4851.
        }
4852.
    
4853.
        var div = $('<div><label/></div>').addClass( classes.sLength );
4854.
        if ( ! settings.aanFeatures.l ) {
4855.
            div[0].id = tableId+'_length';
4856.
        }
4857.
    
4858.
        div.children().append(
4859.
            settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
4860.
        );
4861.
    
4862.
        // Can't use `select` variable as user might provide their own and the
4863.
        // reference is broken by the use of outerHTML
4864.
        $('select', div)
4865.
            .val( settings._iDisplayLength )
4866.
            .on( 'change.DT', function(e) {
4867.
                _fnLengthChange( settings, $(this).val() );
4868.
                _fnDraw( settings );
4869.
            } );
4870.
    
4871.
        // Update node value whenever anything changes the table's length
4872.
        $(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
4873.
            if ( settings === s ) {
4874.
                $('select', div).val( len );
4875.
            }
4876.
        } );
4877.
    
4878.
        return div[0];
4879.
    }
4880.
    
4881.
    
4882.
    
4883.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4884.
     * Note that most of the paging logic is done in
4885.
     * DataTable.ext.pager
4886.
     */
4887.
    
4888.
    /**
4889.
     * Generate the node required for default pagination
4890.
     *  @param {object} oSettings dataTables settings object
4891.
     *  @returns {node} Pagination feature node
4892.
     *  @memberof DataTable#oApi
4893.
     */
4894.
    function _fnFeatureHtmlPaginate ( settings )
4895.
    {
4896.
        var
4897.
            type   = settings.sPaginationType,
4898.
            plugin = DataTable.ext.pager[ type ],
4899.
            modern = typeof plugin === 'function',
4900.
            redraw = function( settings ) {
4901.
                _fnDraw( settings );
4902.
            },
4903.
            node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
4904.
            features = settings.aanFeatures;
4905.
    
4906.
        if ( ! modern ) {
4907.
            plugin.fnInit( settings, node, redraw );
4908.
        }
4909.
    
4910.
        /* Add a draw callback for the pagination on first instance, to update the paging display */
4911.
        if ( ! features.p )
4912.
        {
4913.
            node.id = settings.sTableId+'_paginate';
4914.
    
4915.
            settings.aoDrawCallback.push( {
4916.
                "fn": function( settings ) {
4917.
                    if ( modern ) {
4918.
                        var
4919.
                            start      = settings._iDisplayStart,
4920.
                            len        = settings._iDisplayLength,
4921.
                            visRecords = settings.fnRecordsDisplay(),
4922.
                            all        = len === -1,
4923.
                            page = all ? 0 : Math.ceil( start / len ),
4924.
                            pages = all ? 1 : Math.ceil( visRecords / len ),
4925.
                            buttons = plugin(page, pages),
4926.
                            i, ien;
4927.
    
4928.
                        for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
4929.
                            _fnRenderer( settings, 'pageButton' )(
4930.
                                settings, features.p[i], i, buttons, page, pages
4931.
                            );
4932.
                        }
4933.
                    }
4934.
                    else {
4935.
                        plugin.fnUpdate( settings, redraw );
4936.
                    }
4937.
                },
4938.
                "sName": "pagination"
4939.
            } );
4940.
        }
4941.
    
4942.
        return node;
4943.
    }
4944.
    
4945.
    
4946.
    /**
4947.
     * Alter the display settings to change the page
4948.
     *  @param {object} settings DataTables settings object
4949.
     *  @param {string|int} action Paging action to take: "first", "previous",
4950.
     *    "next" or "last" or page number to jump to (integer)
4951.
     *  @param [bool] redraw Automatically draw the update or not
4952.
     *  @returns {bool} true page has changed, false - no change
4953.
     *  @memberof DataTable#oApi
4954.
     */
4955.
    function _fnPageChange ( settings, action, redraw )
4956.
    {
4957.
        var
4958.
            start     = settings._iDisplayStart,
4959.
            len       = settings._iDisplayLength,
4960.
            records   = settings.fnRecordsDisplay();
4961.
    
4962.
        if ( records === 0 || len === -1 )
4963.
        {
4964.
            start = 0;
4965.
        }
4966.
        else if ( typeof action === "number" )
4967.
        {
4968.
            start = action * len;
4969.
    
4970.
            if ( start > records )
4971.
            {
4972.
                start = 0;
4973.
            }
4974.
        }
4975.
        else if ( action == "first" )
4976.
        {
4977.
            start = 0;
4978.
        }
4979.
        else if ( action == "previous" )
4980.
        {
4981.
            start = len >= 0 ?
4982.
                start - len :
4983.
                0;
4984.
    
4985.
            if ( start < 0 )
4986.
            {
4987.
              start = 0;
4988.
            }
4989.
        }
4990.
        else if ( action == "next" )
4991.
        {
4992.
            if ( start + len < records )
4993.
            {
4994.
                start += len;
4995.
            }
4996.
        }
4997.
        else if ( action == "last" )
4998.
        {
4999.
            start = Math.floor( (records-1) / len) * len;
5000.
        }
5001.
        else
5002.
        {
5003.
            _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
5004.
        }
5005.
    
5006.
        var changed = settings._iDisplayStart !== start;
5007.
        settings._iDisplayStart = start;
5008.
    
5009.
        if ( changed ) {
5010.
            _fnCallbackFire( settings, null, 'page', [settings] );
5011.
    
5012.
            if ( redraw ) {
5013.
                _fnDraw( settings );
5014.
            }
5015.
        }
5016.
    
5017.
        return changed;
5018.
    }
5019.
    
5020.
    
5021.
    
5022.
    /**
5023.
     * Generate the node required for the processing node
5024.
     *  @param {object} settings dataTables settings object
5025.
     *  @returns {node} Processing element
5026.
     *  @memberof DataTable#oApi
5027.
     */
5028.
    function _fnFeatureHtmlProcessing ( settings )
5029.
    {
5030.
        return $('<div/>', {
5031.
                'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
5032.
                'class': settings.oClasses.sProcessing
5033.
            } )
5034.
            .html( settings.oLanguage.sProcessing )
5035.
            .insertBefore( settings.nTable )[0];
5036.
    }
5037.
    
5038.
    
5039.
    /**
5040.
     * Display or hide the processing indicator
5041.
     *  @param {object} settings dataTables settings object
5042.
     *  @param {bool} show Show the processing indicator (true) or not (false)
5043.
     *  @memberof DataTable#oApi
5044.
     */
5045.
    function _fnProcessingDisplay ( settings, show )
5046.
    {
5047.
        if ( settings.oFeatures.bProcessing ) {
5048.
            $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
5049.
        }
5050.
    
5051.
        _fnCallbackFire( settings, null, 'processing', [settings, show] );
5052.
    }
5053.
    
5054.
    /**
5055.
     * Add any control elements for the table - specifically scrolling
5056.
     *  @param {object} settings dataTables settings object
5057.
     *  @returns {node} Node to add to the DOM
5058.
     *  @memberof DataTable#oApi
5059.
     */
5060.
    function _fnFeatureHtmlTable ( settings )
5061.
    {
5062.
        var table = $(settings.nTable);
5063.
    
5064.
        // Add the ARIA grid role to the table
5065.
        table.attr( 'role', 'grid' );
5066.
    
5067.
        // Scrolling from here on in
5068.
        var scroll = settings.oScroll;
5069.
    
5070.
        if ( scroll.sX === '' && scroll.sY === '' ) {
5071.
            return settings.nTable;
5072.
        }
5073.
    
5074.
        var scrollX = scroll.sX;
5075.
        var scrollY = scroll.sY;
5076.
        var classes = settings.oClasses;
5077.
        var caption = table.children('caption');
5078.
        var captionSide = caption.length ? caption[0]._captionSide : null;
5079.
        var headerClone = $( table[0].cloneNode(false) );
5080.
        var footerClone = $( table[0].cloneNode(false) );
5081.
        var footer = table.children('tfoot');
5082.
        var _div = '<div/>';
5083.
        var size = function ( s ) {
5084.
            return !s ? null : _fnStringToCss( s );
5085.
        };
5086.
    
5087.
        if ( ! footer.length ) {
5088.
            footer = null;
5089.
        }
5090.
    
5091.
        /*
5092.
         * The HTML structure that we want to generate in this function is:
5093.
         *  div - scroller
5094.
         *    div - scroll head
5095.
         *      div - scroll head inner
5096.
         *        table - scroll head table
5097.
         *          thead - thead
5098.
         *    div - scroll body
5099.
         *      table - table (master table)
5100.
         *        thead - thead clone for sizing
5101.
         *        tbody - tbody
5102.
         *    div - scroll foot
5103.
         *      div - scroll foot inner
5104.
         *        table - scroll foot table
5105.
         *          tfoot - tfoot
5106.
         */
5107.
        var scroller = $( _div, { 'class': classes.sScrollWrapper } )
5108.
            .append(
5109.
                $(_div, { 'class': classes.sScrollHead } )
5110.
                    .css( {
5111.
                        overflow: 'hidden',
5112.
                        position: 'relative',
5113.
                        border: 0,
5114.
                        width: scrollX ? size(scrollX) : '100%'
5115.
                    } )
5116.
                    .append(
5117.
                        $(_div, { 'class': classes.sScrollHeadInner } )
5118.
                            .css( {
5119.
                                'box-sizing': 'content-box',
5120.
                                width: scroll.sXInner || '100%'
5121.
                            } )
5122.
                            .append(
5123.
                                headerClone
5124.
                                    .removeAttr('id')
5125.
                                    .css( 'margin-left', 0 )
5126.
                                    .append( captionSide === 'top' ? caption : null )
5127.
                                    .append(
5128.
                                        table.children('thead')
5129.
                                    )
5130.
                            )
5131.
                    )
5132.
            )
5133.
            .append(
5134.
                $(_div, { 'class': classes.sScrollBody } )
5135.
                    .css( {
5136.
                        position: 'relative',
5137.
                        overflow: 'auto',
5138.
                        width: size( scrollX )
5139.
                    } )
5140.
                    .append( table )
5141.
            );
5142.
    
5143.
        if ( footer ) {
5144.
            scroller.append(
5145.
                $(_div, { 'class': classes.sScrollFoot } )
5146.
                    .css( {
5147.
                        overflow: 'hidden',
5148.
                        border: 0,
5149.
                        width: scrollX ? size(scrollX) : '100%'
5150.
                    } )
5151.
                    .append(
5152.
                        $(_div, { 'class': classes.sScrollFootInner } )
5153.
                            .append(
5154.
                                footerClone
5155.
                                    .removeAttr('id')
5156.
                                    .css( 'margin-left', 0 )
5157.
                                    .append( captionSide === 'bottom' ? caption : null )
5158.
                                    .append(
5159.
                                        table.children('tfoot')
5160.
                                    )
5161.
                            )
5162.
                    )
5163.
            );
5164.
        }
5165.
    
5166.
        var children = scroller.children();
5167.
        var scrollHead = children[0];
5168.
        var scrollBody = children[1];
5169.
        var scrollFoot = footer ? children[2] : null;
5170.
    
5171.
        // When the body is scrolled, then we also want to scroll the headers
5172.
        if ( scrollX ) {
5173.
            $(scrollBody).on( 'scroll.DT', function (e) {
5174.
                var scrollLeft = this.scrollLeft;
5175.
    
5176.
                scrollHead.scrollLeft = scrollLeft;
5177.
    
5178.
                if ( footer ) {
5179.
                    scrollFoot.scrollLeft = scrollLeft;
5180.
                }
5181.
            } );
5182.
        }
5183.
    
5184.
        $(scrollBody).css('max-height', scrollY);
5185.
        if (! scroll.bCollapse) {
5186.
            $(scrollBody).css('height', scrollY);
5187.
        }
5188.
    
5189.
        settings.nScrollHead = scrollHead;
5190.
        settings.nScrollBody = scrollBody;
5191.
        settings.nScrollFoot = scrollFoot;
5192.
    
5193.
        // On redraw - align columns
5194.
        settings.aoDrawCallback.push( {
5195.
            "fn": _fnScrollDraw,
5196.
            "sName": "scrolling"
5197.
        } );
5198.
    
5199.
        return scroller[0];
5200.
    }
5201.
    
5202.
    
5203.
    
5204.
    /**
5205.
     * Update the header, footer and body tables for resizing - i.e. column
5206.
     * alignment.
5207.
     *
5208.
     * Welcome to the most horrible function DataTables. The process that this
5209.
     * function follows is basically:
5210.
     *   1. Re-create the table inside the scrolling div
5211.
     *   2. Take live measurements from the DOM
5212.
     *   3. Apply the measurements to align the columns
5213.
     *   4. Clean up
5214.
     *
5215.
     *  @param {object} settings dataTables settings object
5216.
     *  @memberof DataTable#oApi
5217.
     */
5218.
    function _fnScrollDraw ( settings )
5219.
    {
5220.
        // Given that this is such a monster function, a lot of variables are use
5221.
        // to try and keep the minimised size as small as possible
5222.
        var
5223.
            scroll         = settings.oScroll,
5224.
            scrollX        = scroll.sX,
5225.
            scrollXInner   = scroll.sXInner,
5226.
            scrollY        = scroll.sY,
5227.
            barWidth       = scroll.iBarWidth,
5228.
            divHeader      = $(settings.nScrollHead),
5229.
            divHeaderStyle = divHeader[0].style,
5230.
            divHeaderInner = divHeader.children('div'),
5231.
            divHeaderInnerStyle = divHeaderInner[0].style,
5232.
            divHeaderTable = divHeaderInner.children('table'),
5233.
            divBodyEl      = settings.nScrollBody,
5234.
            divBody        = $(divBodyEl),
5235.
            divBodyStyle   = divBodyEl.style,
5236.
            divFooter      = $(settings.nScrollFoot),
5237.
            divFooterInner = divFooter.children('div'),
5238.
            divFooterTable = divFooterInner.children('table'),
5239.
            header         = $(settings.nTHead),
5240.
            table          = $(settings.nTable),
5241.
            tableEl        = table[0],
5242.
            tableStyle     = tableEl.style,
5243.
            footer         = settings.nTFoot ? $(settings.nTFoot) : null,
5244.
            browser        = settings.oBrowser,
5245.
            ie67           = browser.bScrollOversize,
5246.
            dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
5247.
            headerTrgEls, footerTrgEls,
5248.
            headerSrcEls, footerSrcEls,
5249.
            headerCopy, footerCopy,
5250.
            headerWidths=[], footerWidths=[],
5251.
            headerContent=[], footerContent=[],
5252.
            idx, correction, sanityWidth,
5253.
            zeroOut = function(nSizer) {
5254.
                var style = nSizer.style;
5255.
                style.paddingTop = "0";
5256.
                style.paddingBottom = "0";
5257.
                style.borderTopWidth = "0";
5258.
                style.borderBottomWidth = "0";
5259.
                style.height = 0;
5260.
            };
5261.
    
5262.
        // If the scrollbar visibility has changed from the last draw, we need to
5263.
        // adjust the column sizes as the table width will have changed to account
5264.
        // for the scrollbar
5265.
        var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
5266.
        
5267.
        if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
5268.
            settings.scrollBarVis = scrollBarVis;
5269.
            _fnAdjustColumnSizing( settings );
5270.
            return; // adjust column sizing will call this function again
5271.
        }
5272.
        else {
5273.
            settings.scrollBarVis = scrollBarVis;
5274.
        }
5275.
    
5276.
        /*
5277.
         * 1. Re-create the table inside the scrolling div
5278.
         */
5279.
    
5280.
        // Remove the old minimised thead and tfoot elements in the inner table
5281.
        table.children('thead, tfoot').remove();
5282.
    
5283.
        if ( footer ) {
5284.
            footerCopy = footer.clone().prependTo( table );
5285.
            footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
5286.
            footerSrcEls = footerCopy.find('tr');
5287.
        }
5288.
    
5289.
        // Clone the current header and footer elements and then place it into the inner table
5290.
        headerCopy = header.clone().prependTo( table );
5291.
        headerTrgEls = header.find('tr'); // original header is in its own table
5292.
        headerSrcEls = headerCopy.find('tr');
5293.
        headerCopy.find('th, td').removeAttr('tabindex');
5294.
    
5295.
    
5296.
        /*
5297.
         * 2. Take live measurements from the DOM - do not alter the DOM itself!
5298.
         */
5299.
    
5300.
        // Remove old sizing and apply the calculated column widths
5301.
        // Get the unique column headers in the newly created (cloned) header. We want to apply the
5302.
        // calculated sizes to this header
5303.
        if ( ! scrollX )
5304.
        {
5305.
            divBodyStyle.width = '100%';
5306.
            divHeader[0].style.width = '100%';
5307.
        }
5308.
    
5309.
        $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
5310.
            idx = _fnVisibleToColumnIndex( settings, i );
5311.
            el.style.width = settings.aoColumns[idx].sWidth;
5312.
        } );
5313.
    
5314.
        if ( footer ) {
5315.
            _fnApplyToChildren( function(n) {
5316.
                n.style.width = "";
5317.
            }, footerSrcEls );
5318.
        }
5319.
    
5320.
        // Size the table as a whole
5321.
        sanityWidth = table.outerWidth();
5322.
        if ( scrollX === "" ) {
5323.
            // No x scrolling
5324.
            tableStyle.width = "100%";
5325.
    
5326.
            // IE7 will make the width of the table when 100% include the scrollbar
5327.
            // - which is shouldn't. When there is a scrollbar we need to take this
5328.
            // into account.
5329.
            if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
5330.
                divBody.css('overflow-y') == "scroll")
5331.
            ) {
5332.
                tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
5333.
            }
5334.
    
5335.
            // Recalculate the sanity width
5336.
            sanityWidth = table.outerWidth();
5337.
        }
5338.
        else if ( scrollXInner !== "" ) {
5339.
            // legacy x scroll inner has been given - use it
5340.
            tableStyle.width = _fnStringToCss(scrollXInner);
5341.
    
5342.
            // Recalculate the sanity width
5343.
            sanityWidth = table.outerWidth();
5344.
        }
5345.
    
5346.
        // Hidden header should have zero height, so remove padding and borders. Then
5347.
        // set the width based on the real headers
5348.
    
5349.
        // Apply all styles in one pass
5350.
        _fnApplyToChildren( zeroOut, headerSrcEls );
5351.
    
5352.
        // Read all widths in next pass
5353.
        _fnApplyToChildren( function(nSizer) {
5354.
            headerContent.push( nSizer.innerHTML );
5355.
            headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5356.
        }, headerSrcEls );
5357.
    
5358.
        // Apply all widths in final pass
5359.
        _fnApplyToChildren( function(nToSize, i) {
5360.
            // Only apply widths to the DataTables detected header cells - this
5361.
            // prevents complex headers from having contradictory sizes applied
5362.
            if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
5363.
                nToSize.style.width = headerWidths[i];
5364.
            }
5365.
        }, headerTrgEls );
5366.
    
5367.
        $(headerSrcEls).height(0);
5368.
    
5369.
        /* Same again with the footer if we have one */
5370.
        if ( footer )
5371.
        {
5372.
            _fnApplyToChildren( zeroOut, footerSrcEls );
5373.
    
5374.
            _fnApplyToChildren( function(nSizer) {
5375.
                footerContent.push( nSizer.innerHTML );
5376.
                footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5377.
            }, footerSrcEls );
5378.
    
5379.
            _fnApplyToChildren( function(nToSize, i) {
5380.
                nToSize.style.width = footerWidths[i];
5381.
            }, footerTrgEls );
5382.
    
5383.
            $(footerSrcEls).height(0);
5384.
        }
5385.
    
5386.
    
5387.
        /*
5388.
         * 3. Apply the measurements
5389.
         */
5390.
    
5391.
        // "Hide" the header and footer that we used for the sizing. We need to keep
5392.
        // the content of the cell so that the width applied to the header and body
5393.
        // both match, but we want to hide it completely. We want to also fix their
5394.
        // width to what they currently are
5395.
        _fnApplyToChildren( function(nSizer, i) {
5396.
            nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
5397.
            nSizer.childNodes[0].style.height = "0";
5398.
            nSizer.childNodes[0].style.overflow = "hidden";
5399.
            nSizer.style.width = headerWidths[i];
5400.
        }, headerSrcEls );
5401.
    
5402.
        if ( footer )
5403.
        {
5404.
            _fnApplyToChildren( function(nSizer, i) {
5405.
                nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
5406.
                nSizer.childNodes[0].style.height = "0";
5407.
                nSizer.childNodes[0].style.overflow = "hidden";
5408.
                nSizer.style.width = footerWidths[i];
5409.
            }, footerSrcEls );
5410.
        }
5411.
    
5412.
        // Sanity check that the table is of a sensible width. If not then we are going to get
5413.
        // misalignment - try to prevent this by not allowing the table to shrink below its min width
5414.
        if ( table.outerWidth() < sanityWidth )
5415.
        {
5416.
            // The min width depends upon if we have a vertical scrollbar visible or not */
5417.
            correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
5418.
                divBody.css('overflow-y') == "scroll")) ?
5419.
                    sanityWidth+barWidth :
5420.
                    sanityWidth;
5421.
    
5422.
            // IE6/7 are a law unto themselves...
5423.
            if ( ie67 && (divBodyEl.scrollHeight >
5424.
                divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
5425.
            ) {
5426.
                tableStyle.width = _fnStringToCss( correction-barWidth );
5427.
            }
5428.
    
5429.
            // And give the user a warning that we've stopped the table getting too small
5430.
            if ( scrollX === "" || scrollXInner !== "" ) {
5431.
                _fnLog( settings, 1, 'Possible column misalignment', 6 );
5432.
            }
5433.
        }
5434.
        else
5435.
        {
5436.
            correction = '100%';
5437.
        }
5438.
    
5439.
        // Apply to the container elements
5440.
        divBodyStyle.width = _fnStringToCss( correction );
5441.
        divHeaderStyle.width = _fnStringToCss( correction );
5442.
    
5443.
        if ( footer ) {
5444.
            settings.nScrollFoot.style.width = _fnStringToCss( correction );
5445.
        }
5446.
    
5447.
    
5448.
        /*
5449.
         * 4. Clean up
5450.
         */
5451.
        if ( ! scrollY ) {
5452.
            /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
5453.
             * the scrollbar height from the visible display, rather than adding it on. We need to
5454.
             * set the height in order to sort this. Don't want to do it in any other browsers.
5455.
             */
5456.
            if ( ie67 ) {
5457.
                divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
5458.
            }
5459.
        }
5460.
    
5461.
        /* Finally set the width's of the header and footer tables */
5462.
        var iOuterWidth = table.outerWidth();
5463.
        divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
5464.
        divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
5465.
    
5466.
        // Figure out if there are scrollbar present - if so then we need a the header and footer to
5467.
        // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5468.
        var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5469.
        var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
5470.
        divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
5471.
    
5472.
        if ( footer ) {
5473.
            divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
5474.
            divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
5475.
            divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
5476.
        }
5477.
    
5478.
        // Correct DOM ordering for colgroup - comes before the thead
5479.
        table.children('colgroup').insertBefore( table.children('thead') );
5480.
    
5481.
        /* Adjust the position of the header in case we loose the y-scrollbar */
5482.
        divBody.trigger('scroll');
5483.
    
5484.
        // If sorting or filtering has occurred, jump the scrolling back to the top
5485.
        // only if we aren't holding the position
5486.
        if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
5487.
            divBodyEl.scrollTop = 0;
5488.
        }
5489.
    }
5490.
    
5491.
    
5492.
    
5493.
    /**
5494.
     * Apply a given function to the display child nodes of an element array (typically
5495.
     * TD children of TR rows
5496.
     *  @param {function} fn Method to apply to the objects
5497.
     *  @param array {nodes} an1 List of elements to look through for display children
5498.
     *  @param array {nodes} an2 Another list (identical structure to the first) - optional
5499.
     *  @memberof DataTable#oApi
5500.
     */
5501.
    function _fnApplyToChildren( fn, an1, an2 )
5502.
    {
5503.
        var index=0, i=0, iLen=an1.length;
5504.
        var nNode1, nNode2;
5505.
    
5506.
        while ( i < iLen ) {
5507.
            nNode1 = an1[i].firstChild;
5508.
            nNode2 = an2 ? an2[i].firstChild : null;
5509.
    
5510.
            while ( nNode1 ) {
5511.
                if ( nNode1.nodeType === 1 ) {
5512.
                    if ( an2 ) {
5513.
                        fn( nNode1, nNode2, index );
5514.
                    }
5515.
                    else {
5516.
                        fn( nNode1, index );
5517.
                    }
5518.
    
5519.
                    index++;
5520.
                }
5521.
    
5522.
                nNode1 = nNode1.nextSibling;
5523.
                nNode2 = an2 ? nNode2.nextSibling : null;
5524.
            }
5525.
    
5526.
            i++;
5527.
        }
5528.
    }
5529.
    
5530.
    
5531.
    
5532.
    var __re_html_remove = /<.*?>/g;
5533.
    
5534.
    
5535.
    /**
5536.
     * Calculate the width of columns for the table
5537.
     *  @param {object} oSettings dataTables settings object
5538.
     *  @memberof DataTable#oApi
5539.
     */
5540.
    function _fnCalculateColumnWidths ( oSettings )
5541.
    {
5542.
        var
5543.
            table = oSettings.nTable,
5544.
            columns = oSettings.aoColumns,
5545.
            scroll = oSettings.oScroll,
5546.
            scrollY = scroll.sY,
5547.
            scrollX = scroll.sX,
5548.
            scrollXInner = scroll.sXInner,
5549.
            columnCount = columns.length,
5550.
            visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
5551.
            headerCells = $('th', oSettings.nTHead),
5552.
            tableWidthAttr = table.getAttribute('width'), // from DOM element
5553.
            tableContainer = table.parentNode,
5554.
            userInputs = false,
5555.
            i, column, columnIdx, width, outerWidth,
5556.
            browser = oSettings.oBrowser,
5557.
            ie67 = browser.bScrollOversize;
5558.
    
5559.
        var styleWidth = table.style.width;
5560.
        if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
5561.
            tableWidthAttr = styleWidth;
5562.
        }
5563.
    
5564.
        /* Convert any user input sizes into pixel sizes */
5565.
        for ( i=0 ; i<visibleColumns.length ; i++ ) {
5566.
            column = columns[ visibleColumns[i] ];
5567.
    
5568.
            if ( column.sWidth !== null ) {
5569.
                column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
5570.
    
5571.
                userInputs = true;
5572.
            }
5573.
        }
5574.
    
5575.
        /* If the number of columns in the DOM equals the number that we have to
5576.
         * process in DataTables, then we can use the offsets that are created by
5577.
         * the web- browser. No custom sizes can be set in order for this to happen,
5578.
         * nor scrolling used
5579.
         */
5580.
        if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
5581.
             columnCount == _fnVisbleColumns( oSettings ) &&
5582.
             columnCount == headerCells.length
5583.
        ) {
5584.
            for ( i=0 ; i<columnCount ; i++ ) {
5585.
                var colIdx = _fnVisibleToColumnIndex( oSettings, i );
5586.
    
5587.
                if ( colIdx !== null ) {
5588.
                    columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
5589.
                }
5590.
            }
5591.
        }
5592.
        else
5593.
        {
5594.
            // Otherwise construct a single row, worst case, table with the widest
5595.
            // node in the data, assign any user defined widths, then insert it into
5596.
            // the DOM and allow the browser to do all the hard work of calculating
5597.
            // table widths
5598.
            var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
5599.
                .css( 'visibility', 'hidden' )
5600.
                .removeAttr( 'id' );
5601.
    
5602.
            // Clean up the table body
5603.
            tmpTable.find('tbody tr').remove();
5604.
            var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
5605.
    
5606.
            // Clone the table header and footer - we can't use the header / footer
5607.
            // from the cloned table, since if scrolling is active, the table's
5608.
            // real header and footer are contained in different table tags
5609.
            tmpTable.find('thead, tfoot').remove();
5610.
            tmpTable
5611.
                .append( $(oSettings.nTHead).clone() )
5612.
                .append( $(oSettings.nTFoot).clone() );
5613.
    
5614.
            // Remove any assigned widths from the footer (from scrolling)
5615.
            tmpTable.find('tfoot th, tfoot td').css('width', '');
5616.
    
5617.
            // Apply custom sizing to the cloned header
5618.
            headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
5619.
    
5620.
            for ( i=0 ; i<visibleColumns.length ; i++ ) {
5621.
                column = columns[ visibleColumns[i] ];
5622.
    
5623.
                headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
5624.
                    _fnStringToCss( column.sWidthOrig ) :
5625.
                    '';
5626.
    
5627.
                // For scrollX we need to force the column width otherwise the
5628.
                // browser will collapse it. If this width is smaller than the
5629.
                // width the column requires, then it will have no effect
5630.
                if ( column.sWidthOrig && scrollX ) {
5631.
                    $( headerCells[i] ).append( $('<div/>').css( {
5632.
                        width: column.sWidthOrig,
5633.
                        margin: 0,
5634.
                        padding: 0,
5635.
                        border: 0,
5636.
                        height: 1
5637.
                    } ) );
5638.
                }
5639.
            }
5640.
    
5641.
            // Find the widest cell for each column and put it into the table
5642.
            if ( oSettings.aoData.length ) {
5643.
                for ( i=0 ; i<visibleColumns.length ; i++ ) {
5644.
                    columnIdx = visibleColumns[i];
5645.
                    column = columns[ columnIdx ];
5646.
    
5647.
                    $( _fnGetWidestNode( oSettings, columnIdx ) )
5648.
                        .clone( false )
5649.
                        .append( column.sContentPadding )
5650.
                        .appendTo( tr );
5651.
                }
5652.
            }
5653.
    
5654.
            // Tidy the temporary table - remove name attributes so there aren't
5655.
            // duplicated in the dom (radio elements for example)
5656.
            $('[name]', tmpTable).removeAttr('name');
5657.
    
5658.
            // Table has been built, attach to the document so we can work with it.
5659.
            // A holding element is used, positioned at the top of the container
5660.
            // with minimal height, so it has no effect on if the container scrolls
5661.
            // or not. Otherwise it might trigger scrolling when it actually isn't
5662.
            // needed
5663.
            var holder = $('<div/>').css( scrollX || scrollY ?
5664.
                    {
5665.
                        position: 'absolute',
5666.
                        top: 0,
5667.
                        left: 0,
5668.
                        height: 1,
5669.
                        right: 0,
5670.
                        overflow: 'hidden'
5671.
                    } :
5672.
                    {}
5673.
                )
5674.
                .append( tmpTable )
5675.
                .appendTo( tableContainer );
5676.
    
5677.
            // When scrolling (X or Y) we want to set the width of the table as 
5678.
            // appropriate. However, when not scrolling leave the table width as it
5679.
            // is. This results in slightly different, but I think correct behaviour
5680.
            if ( scrollX && scrollXInner ) {
5681.
                tmpTable.width( scrollXInner );
5682.
            }
5683.
            else if ( scrollX ) {
5684.
                tmpTable.css( 'width', 'auto' );
5685.
                tmpTable.removeAttr('width');
5686.
    
5687.
                // If there is no width attribute or style, then allow the table to
5688.
                // collapse
5689.
                if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
5690.
                    tmpTable.width( tableContainer.clientWidth );
5691.
                }
5692.
            }
5693.
            else if ( scrollY ) {
5694.
                tmpTable.width( tableContainer.clientWidth );
5695.
            }
5696.
            else if ( tableWidthAttr ) {
5697.
                tmpTable.width( tableWidthAttr );
5698.
            }
5699.
    
5700.
            // Get the width of each column in the constructed table - we need to
5701.
            // know the inner width (so it can be assigned to the other table's
5702.
            // cells) and the outer width so we can calculate the full width of the
5703.
            // table. This is safe since DataTables requires a unique cell for each
5704.
            // column, but if ever a header can span multiple columns, this will
5705.
            // need to be modified.
5706.
            var total = 0;
5707.
            for ( i=0 ; i<visibleColumns.length ; i++ ) {
5708.
                var cell = $(headerCells[i]);
5709.
                var border = cell.outerWidth() - cell.width();
5710.
    
5711.
                // Use getBounding... where possible (not IE8-) because it can give
5712.
                // sub-pixel accuracy, which we then want to round up!
5713.
                var bounding = browser.bBounding ?
5714.
                    Math.ceil( headerCells[i].getBoundingClientRect().width ) :
5715.
                    cell.outerWidth();
5716.
    
5717.
                // Total is tracked to remove any sub-pixel errors as the outerWidth
5718.
                // of the table might not equal the total given here (IE!).
5719.
                total += bounding;
5720.
    
5721.
                // Width for each column to use
5722.
                columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
5723.
            }
5724.
    
5725.
            table.style.width = _fnStringToCss( total );
5726.
    
5727.
            // Finished with the table - ditch it
5728.
            holder.remove();
5729.
        }
5730.
    
5731.
        // If there is a width attr, we want to attach an event listener which
5732.
        // allows the table sizing to automatically adjust when the window is
5733.
        // resized. Use the width attr rather than CSS, since we can't know if the
5734.
        // CSS is a relative value or absolute - DOM read is always px.
5735.
        if ( tableWidthAttr ) {
5736.
            table.style.width = _fnStringToCss( tableWidthAttr );
5737.
        }
5738.
    
5739.
        if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
5740.
            var bindResize = function () {
5741.
                $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
5742.
                    _fnAdjustColumnSizing( oSettings );
5743.
                } ) );
5744.
            };
5745.
    
5746.
            // IE6/7 will crash if we bind a resize event handler on page load.
5747.
            // To be removed in 1.11 which drops IE6/7 support
5748.
            if ( ie67 ) {
5749.
                setTimeout( bindResize, 1000 );
5750.
            }
5751.
            else {
5752.
                bindResize();
5753.
            }
5754.
    
5755.
            oSettings._reszEvt = true;
5756.
        }
5757.
    }
5758.
    
5759.
    
5760.
    /**
5761.
     * Throttle the calls to a function. Arguments and context are maintained for
5762.
     * the throttled function
5763.
     *  @param {function} fn Function to be called
5764.
     *  @param {int} [freq=200] call frequency in mS
5765.
     *  @returns {function} wrapped function
5766.
     *  @memberof DataTable#oApi
5767.
     */
5768.
    var _fnThrottle = DataTable.util.throttle;
5769.
    
5770.
    
5771.
    /**
5772.
     * Convert a CSS unit width to pixels (e.g. 2em)
5773.
     *  @param {string} width width to be converted
5774.
     *  @param {node} parent parent to get the with for (required for relative widths) - optional
5775.
     *  @returns {int} width in pixels
5776.
     *  @memberof DataTable#oApi
5777.
     */
5778.
    function _fnConvertToWidth ( width, parent )
5779.
    {
5780.
        if ( ! width ) {
5781.
            return 0;
5782.
        }
5783.
    
5784.
        var n = $('<div/>')
5785.
            .css( 'width', _fnStringToCss( width ) )
5786.
            .appendTo( parent || document.body );
5787.
    
5788.
        var val = n[0].offsetWidth;
5789.
        n.remove();
5790.
    
5791.
        return val;
5792.
    }
5793.
    
5794.
    
5795.
    /**
5796.
     * Get the widest node
5797.
     *  @param {object} settings dataTables settings object
5798.
     *  @param {int} colIdx column of interest
5799.
     *  @returns {node} widest table node
5800.
     *  @memberof DataTable#oApi
5801.
     */
5802.
    function _fnGetWidestNode( settings, colIdx )
5803.
    {
5804.
        var idx = _fnGetMaxLenString( settings, colIdx );
5805.
        if ( idx < 0 ) {
5806.
            return null;
5807.
        }
5808.
    
5809.
        var data = settings.aoData[ idx ];
5810.
        return ! data.nTr ? // Might not have been created when deferred rendering
5811.
            $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
5812.
            data.anCells[ colIdx ];
5813.
    }
5814.
    
5815.
    
5816.
    /**
5817.
     * Get the maximum strlen for each data column
5818.
     *  @param {object} settings dataTables settings object
5819.
     *  @param {int} colIdx column of interest
5820.
     *  @returns {string} max string length for each column
5821.
     *  @memberof DataTable#oApi
5822.
     */
5823.
    function _fnGetMaxLenString( settings, colIdx )
5824.
    {
5825.
        var s, max=-1, maxIdx = -1;
5826.
    
5827.
        for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
5828.
            s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
5829.
            s = s.replace( __re_html_remove, '' );
5830.
            s = s.replace( /&nbsp;/g, ' ' );
5831.
    
5832.
            if ( s.length > max ) {
5833.
                max = s.length;
5834.
                maxIdx = i;
5835.
            }
5836.
        }
5837.
    
5838.
        return maxIdx;
5839.
    }
5840.
    
5841.
    
5842.
    /**
5843.
     * Append a CSS unit (only if required) to a string
5844.
     *  @param {string} value to css-ify
5845.
     *  @returns {string} value with css unit
5846.
     *  @memberof DataTable#oApi
5847.
     */
5848.
    function _fnStringToCss( s )
5849.
    {
5850.
        if ( s === null ) {
5851.
            return '0px';
5852.
        }
5853.
    
5854.
        if ( typeof s == 'number' ) {
5855.
            return s < 0 ?
5856.
                '0px' :
5857.
                s+'px';
5858.
        }
5859.
    
5860.
        // Check it has a unit character already
5861.
        return s.match(/\d$/) ?
5862.
            s+'px' :
5863.
            s;
5864.
    }
5865.
    
5866.
    
5867.
    
5868.
    function _fnSortFlatten ( settings )
5869.
    {
5870.
        var
5871.
            i, iLen, k, kLen,
5872.
            aSort = [],
5873.
            aiOrig = [],
5874.
            aoColumns = settings.aoColumns,
5875.
            aDataSort, iCol, sType, srcCol,
5876.
            fixed = settings.aaSortingFixed,
5877.
            fixedObj = $.isPlainObject( fixed ),
5878.
            nestedSort = [],
5879.
            add = function ( a ) {
5880.
                if ( a.length && ! $.isArray( a[0] ) ) {
5881.
                    // 1D array
5882.
                    nestedSort.push( a );
5883.
                }
5884.
                else {
5885.
                    // 2D array
5886.
                    $.merge( nestedSort, a );
5887.
                }
5888.
            };
5889.
    
5890.
        // Build the sort array, with pre-fix and post-fix options if they have been
5891.
        // specified
5892.
        if ( $.isArray( fixed ) ) {
5893.
            add( fixed );
5894.
        }
5895.
    
5896.
        if ( fixedObj && fixed.pre ) {
5897.
            add( fixed.pre );
5898.
        }
5899.
    
5900.
        add( settings.aaSorting );
5901.
    
5902.
        if (fixedObj && fixed.post ) {
5903.
            add( fixed.post );
5904.
        }
5905.
    
5906.
        for ( i=0 ; i<nestedSort.length ; i++ )
5907.
        {
5908.
            srcCol = nestedSort[i][0];
5909.
            aDataSort = aoColumns[ srcCol ].aDataSort;
5910.
    
5911.
            for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
5912.
            {
5913.
                iCol = aDataSort[k];
5914.
                sType = aoColumns[ iCol ].sType || 'string';
5915.
    
5916.
                if ( nestedSort[i]._idx === undefined ) {
5917.
                    nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
5918.
                }
5919.
    
5920.
                aSort.push( {
5921.
                    src:       srcCol,
5922.
                    col:       iCol,
5923.
                    dir:       nestedSort[i][1],
5924.
                    index:     nestedSort[i]._idx,
5925.
                    type:      sType,
5926.
                    formatter: DataTable.ext.type.order[ sType+"-pre" ]
5927.
                } );
5928.
            }
5929.
        }
5930.
    
5931.
        return aSort;
5932.
    }
5933.
    
5934.
    /**
5935.
     * Change the order of the table
5936.
     *  @param {object} oSettings dataTables settings object
5937.
     *  @memberof DataTable#oApi
5938.
     *  @todo This really needs split up!
5939.
     */
5940.
    function _fnSort ( oSettings )
5941.
    {
5942.
        var
5943.
            i, ien, iLen, j, jLen, k, kLen,
5944.
            sDataType, nTh,
5945.
            aiOrig = [],
5946.
            oExtSort = DataTable.ext.type.order,
5947.
            aoData = oSettings.aoData,
5948.
            aoColumns = oSettings.aoColumns,
5949.
            aDataSort, data, iCol, sType, oSort,
5950.
            formatters = 0,
5951.
            sortCol,
5952.
            displayMaster = oSettings.aiDisplayMaster,
5953.
            aSort;
5954.
    
5955.
        // Resolve any column types that are unknown due to addition or invalidation
5956.
        // @todo Can this be moved into a 'data-ready' handler which is called when
5957.
        //   data is going to be used in the table?
5958.
        _fnColumnTypes( oSettings );
5959.
    
5960.
        aSort = _fnSortFlatten( oSettings );
5961.
    
5962.
        for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
5963.
            sortCol = aSort[i];
5964.
    
5965.
            // Track if we can use the fast sort algorithm
5966.
            if ( sortCol.formatter ) {
5967.
                formatters++;
5968.
            }
5969.
    
5970.
            // Load the data needed for the sort, for each cell
5971.
            _fnSortData( oSettings, sortCol.col );
5972.
        }
5973.
    
5974.
        /* No sorting required if server-side or no sorting array */
5975.
        if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
5976.
        {
5977.
            // Create a value - key array of the current row positions such that we can use their
5978.
            // current position during the sort, if values match, in order to perform stable sorting
5979.
            for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
5980.
                aiOrig[ displayMaster[i] ] = i;
5981.
            }
5982.
    
5983.
            /* Do the sort - here we want multi-column sorting based on a given data source (column)
5984.
             * and sorting function (from oSort) in a certain direction. It's reasonably complex to
5985.
             * follow on it's own, but this is what we want (example two column sorting):
5986.
             *  fnLocalSorting = function(a,b){
5987.
             *    var iTest;
5988.
             *    iTest = oSort['string-asc']('data11', 'data12');
5989.
             *      if (iTest !== 0)
5990.
             *        return iTest;
5991.
             *    iTest = oSort['numeric-desc']('data21', 'data22');
5992.
             *    if (iTest !== 0)
5993.
             *      return iTest;
5994.
             *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
5995.
             *  }
5996.
             * Basically we have a test for each sorting column, if the data in that column is equal,
5997.
             * test the next column. If all columns match, then we use a numeric sort on the row
5998.
             * positions in the original data array to provide a stable sort.
5999.
             *
6000.
             * Note - I know it seems excessive to have two sorting methods, but the first is around
6001.
             * 15% faster, so the second is only maintained for backwards compatibility with sorting
6002.
             * methods which do not have a pre-sort formatting function.
6003.
             */
6004.
            if ( formatters === aSort.length ) {
6005.
                // All sort types have formatting functions
6006.
                displayMaster.sort( function ( a, b ) {
6007.
                    var
6008.
                        x, y, k, test, sort,
6009.
                        len=aSort.length,
6010.
                        dataA = aoData[a]._aSortData,
6011.
                        dataB = aoData[b]._aSortData;
6012.
    
6013.
                    for ( k=0 ; k<len ; k++ ) {
6014.
                        sort = aSort[k];
6015.
    
6016.
                        x = dataA[ sort.col ];
6017.
                        y = dataB[ sort.col ];
6018.
    
6019.
                        test = x<y ? -1 : x>y ? 1 : 0;
6020.
                        if ( test !== 0 ) {
6021.
                            return sort.dir === 'asc' ? test : -test;
6022.
                        }
6023.
                    }
6024.
    
6025.
                    x = aiOrig[a];
6026.
                    y = aiOrig[b];
6027.
                    return x<y ? -1 : x>y ? 1 : 0;
6028.
                } );
6029.
            }
6030.
            else {
6031.
                // Depreciated - remove in 1.11 (providing a plug-in option)
6032.
                // Not all sort types have formatting methods, so we have to call their sorting
6033.
                // methods.
6034.
                displayMaster.sort( function ( a, b ) {
6035.
                    var
6036.
                        x, y, k, l, test, sort, fn,
6037.
                        len=aSort.length,
6038.
                        dataA = aoData[a]._aSortData,
6039.
                        dataB = aoData[b]._aSortData;
6040.
    
6041.
                    for ( k=0 ; k<len ; k++ ) {
6042.
                        sort = aSort[k];
6043.
    
6044.
                        x = dataA[ sort.col ];
6045.
                        y = dataB[ sort.col ];
6046.
    
6047.
                        fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
6048.
                        test = fn( x, y );
6049.
                        if ( test !== 0 ) {
6050.
                            return test;
6051.
                        }
6052.
                    }
6053.
    
6054.
                    x = aiOrig[a];
6055.
                    y = aiOrig[b];
6056.
                    return x<y ? -1 : x>y ? 1 : 0;
6057.
                } );
6058.
            }
6059.
        }
6060.
    
6061.
        /* Tell the draw function that we have sorted the data */
6062.
        oSettings.bSorted = true;
6063.
    }
6064.
    
6065.
    
6066.
    function _fnSortAria ( settings )
6067.
    {
6068.
        var label;
6069.
        var nextSort;
6070.
        var columns = settings.aoColumns;
6071.
        var aSort = _fnSortFlatten( settings );
6072.
        var oAria = settings.oLanguage.oAria;
6073.
    
6074.
        // ARIA attributes - need to loop all columns, to update all (removing old
6075.
        // attributes as needed)
6076.
        for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
6077.
        {
6078.
            var col = columns[i];
6079.
            var asSorting = col.asSorting;
6080.
            var sTitle = col.sTitle.replace( /<.*?>/g, "" );
6081.
            var th = col.nTh;
6082.
    
6083.
            // IE7 is throwing an error when setting these properties with jQuery's
6084.
            // attr() and removeAttr() methods...
6085.
            th.removeAttribute('aria-sort');
6086.
    
6087.
            /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
6088.
            if ( col.bSortable ) {
6089.
                if ( aSort.length > 0 && aSort[0].col == i ) {
6090.
                    th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
6091.
                    nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
6092.
                }
6093.
                else {
6094.
                    nextSort = asSorting[0];
6095.
                }
6096.
    
6097.
                label = sTitle + ( nextSort === "asc" ?
6098.
                    oAria.sSortAscending :
6099.
                    oAria.sSortDescending
6100.
                );
6101.
            }
6102.
            else {
6103.
                label = sTitle;
6104.
            }
6105.
    
6106.
            th.setAttribute('aria-label', label);
6107.
        }
6108.
    }
6109.
    
6110.
    
6111.
    /**
6112.
     * Function to run on user sort request
6113.
     *  @param {object} settings dataTables settings object
6114.
     *  @param {node} attachTo node to attach the handler to
6115.
     *  @param {int} colIdx column sorting index
6116.
     *  @param {boolean} [append=false] Append the requested sort to the existing
6117.
     *    sort if true (i.e. multi-column sort)
6118.
     *  @param {function} [callback] callback function
6119.
     *  @memberof DataTable#oApi
6120.
     */
6121.
    function _fnSortListener ( settings, colIdx, append, callback )
6122.
    {
6123.
        var col = settings.aoColumns[ colIdx ];
6124.
        var sorting = settings.aaSorting;
6125.
        var asSorting = col.asSorting;
6126.
        var nextSortIdx;
6127.
        var next = function ( a, overflow ) {
6128.
            var idx = a._idx;
6129.
            if ( idx === undefined ) {
6130.
                idx = $.inArray( a[1], asSorting );
6131.
            }
6132.
    
6133.
            return idx+1 < asSorting.length ?
6134.
                idx+1 :
6135.
                overflow ?
6136.
                    null :
6137.
                    0;
6138.
        };
6139.
    
6140.
        // Convert to 2D array if needed
6141.
        if ( typeof sorting[0] === 'number' ) {
6142.
            sorting = settings.aaSorting = [ sorting ];
6143.
        }
6144.
    
6145.
        // If appending the sort then we are multi-column sorting
6146.
        if ( append && settings.oFeatures.bSortMulti ) {
6147.
            // Are we already doing some kind of sort on this column?
6148.
            var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
6149.
    
6150.
            if ( sortIdx !== -1 ) {
6151.
                // Yes, modify the sort
6152.
                nextSortIdx = next( sorting[sortIdx], true );
6153.
    
6154.
                if ( nextSortIdx === null && sorting.length === 1 ) {
6155.
                    nextSortIdx = 0; // can't remove sorting completely
6156.
                }
6157.
    
6158.
                if ( nextSortIdx === null ) {
6159.
                    sorting.splice( sortIdx, 1 );
6160.
                }
6161.
                else {
6162.
                    sorting[sortIdx][1] = asSorting[ nextSortIdx ];
6163.
                    sorting[sortIdx]._idx = nextSortIdx;
6164.
                }
6165.
            }
6166.
            else {
6167.
                // No sort on this column yet
6168.
                sorting.push( [ colIdx, asSorting[0], 0 ] );
6169.
                sorting[sorting.length-1]._idx = 0;
6170.
            }
6171.
        }
6172.
        else if ( sorting.length && sorting[0][0] == colIdx ) {
6173.
            // Single column - already sorting on this column, modify the sort
6174.
            nextSortIdx = next( sorting[0] );
6175.
    
6176.
            sorting.length = 1;
6177.
            sorting[0][1] = asSorting[ nextSortIdx ];
6178.
            sorting[0]._idx = nextSortIdx;
6179.
        }
6180.
        else {
6181.
            // Single column - sort only on this column
6182.
            sorting.length = 0;
6183.
            sorting.push( [ colIdx, asSorting[0] ] );
6184.
            sorting[0]._idx = 0;
6185.
        }
6186.
    
6187.
        // Run the sort by calling a full redraw
6188.
        _fnReDraw( settings );
6189.
    
6190.
        // callback used for async user interaction
6191.
        if ( typeof callback == 'function' ) {
6192.
            callback( settings );
6193.
        }
6194.
    }
6195.
    
6196.
    
6197.
    /**
6198.
     * Attach a sort handler (click) to a node
6199.
     *  @param {object} settings dataTables settings object
6200.
     *  @param {node} attachTo node to attach the handler to
6201.
     *  @param {int} colIdx column sorting index
6202.
     *  @param {function} [callback] callback function
6203.
     *  @memberof DataTable#oApi
6204.
     */
6205.
    function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
6206.
    {
6207.
        var col = settings.aoColumns[ colIdx ];
6208.
    
6209.
        _fnBindAction( attachTo, {}, function (e) {
6210.
            /* If the column is not sortable - don't to anything */
6211.
            if ( col.bSortable === false ) {
6212.
                return;
6213.
            }
6214.
    
6215.
            // If processing is enabled use a timeout to allow the processing
6216.
            // display to be shown - otherwise to it synchronously
6217.
            if ( settings.oFeatures.bProcessing ) {
6218.
                _fnProcessingDisplay( settings, true );
6219.
    
6220.
                setTimeout( function() {
6221.
                    _fnSortListener( settings, colIdx, e.shiftKey, callback );
6222.
    
6223.
                    // In server-side processing, the draw callback will remove the
6224.
                    // processing display
6225.
                    if ( _fnDataSource( settings ) !== 'ssp' ) {
6226.
                        _fnProcessingDisplay( settings, false );
6227.
                    }
6228.
                }, 0 );
6229.
            }
6230.
            else {
6231.
                _fnSortListener( settings, colIdx, e.shiftKey, callback );
6232.
            }
6233.
        } );
6234.
    }
6235.
    
6236.
    
6237.
    /**
6238.
     * Set the sorting classes on table's body, Note: it is safe to call this function
6239.
     * when bSort and bSortClasses are false
6240.
     *  @param {object} oSettings dataTables settings object
6241.
     *  @memberof DataTable#oApi
6242.
     */
6243.
    function _fnSortingClasses( settings )
6244.
    {
6245.
        var oldSort = settings.aLastSort;
6246.
        var sortClass = settings.oClasses.sSortColumn;
6247.
        var sort = _fnSortFlatten( settings );
6248.
        var features = settings.oFeatures;
6249.
        var i, ien, colIdx;
6250.
    
6251.
        if ( features.bSort && features.bSortClasses ) {
6252.
            // Remove old sorting classes
6253.
            for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
6254.
                colIdx = oldSort[i].src;
6255.
    
6256.
                // Remove column sorting
6257.
                $( _pluck( settings.aoData, 'anCells', colIdx ) )
6258.
                    .removeClass( sortClass + (i<2 ? i+1 : 3) );
6259.
            }
6260.
    
6261.
            // Add new column sorting
6262.
            for ( i=0, ien=sort.length ; i<ien ; i++ ) {
6263.
                colIdx = sort[i].src;
6264.
    
6265.
                $( _pluck( settings.aoData, 'anCells', colIdx ) )
6266.
                    .addClass( sortClass + (i<2 ? i+1 : 3) );
6267.
            }
6268.
        }
6269.
    
6270.
        settings.aLastSort = sort;
6271.
    }
6272.
    
6273.
    
6274.
    // Get the data to sort a column, be it from cache, fresh (populating the
6275.
    // cache), or from a sort formatter
6276.
    function _fnSortData( settings, idx )
6277.
    {
6278.
        // Custom sorting function - provided by the sort data type
6279.
        var column = settings.aoColumns[ idx ];
6280.
        var customSort = DataTable.ext.order[ column.sSortDataType ];
6281.
        var customData;
6282.
    
6283.
        if ( customSort ) {
6284.
            customData = customSort.call( settings.oInstance, settings, idx,
6285.
                _fnColumnIndexToVisible( settings, idx )
6286.
            );
6287.
        }
6288.
    
6289.
        // Use / populate cache
6290.
        var row, cellData;
6291.
        var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
6292.
    
6293.
        for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
6294.
            row = settings.aoData[i];
6295.
    
6296.
            if ( ! row._aSortData ) {
6297.
                row._aSortData = [];
6298.
            }
6299.
    
6300.
            if ( ! row._aSortData[idx] || customSort ) {
6301.
                cellData = customSort ?
6302.
                    customData[i] : // If there was a custom sort function, use data from there
6303.
                    _fnGetCellData( settings, i, idx, 'sort' );
6304.
    
6305.
                row._aSortData[ idx ] = formatter ?
6306.
                    formatter( cellData ) :
6307.
                    cellData;
6308.
            }
6309.
        }
6310.
    }
6311.
    
6312.
    
6313.
    
6314.
    /**
6315.
     * Save the state of a table
6316.
     *  @param {object} oSettings dataTables settings object
6317.
     *  @memberof DataTable#oApi
6318.
     */
6319.
    function _fnSaveState ( settings )
6320.
    {
6321.
        if ( !settings.oFeatures.bStateSave || settings.bDestroying )
6322.
        {
6323.
            return;
6324.
        }
6325.
    
6326.
        /* Store the interesting variables */
6327.
        var state = {
6328.
            time:    +new Date(),
6329.
            start:   settings._iDisplayStart,
6330.
            length:  settings._iDisplayLength,
6331.
            order:   $.extend( true, [], settings.aaSorting ),
6332.
            search:  _fnSearchToCamel( settings.oPreviousSearch ),
6333.
            columns: $.map( settings.aoColumns, function ( col, i ) {
6334.
                return {
6335.
                    visible: col.bVisible,
6336.
                    search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
6337.
                };
6338.
            } )
6339.
        };
6340.
    
6341.
        _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
6342.
    
6343.
        settings.oSavedState = state;
6344.
        settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
6345.
    }
6346.
    
6347.
    
6348.
    /**
6349.
     * Attempt to load a saved table state
6350.
     *  @param {object} oSettings dataTables settings object
6351.
     *  @param {object} oInit DataTables init object so we can override settings
6352.
     *  @param {function} callback Callback to execute when the state has been loaded
6353.
     *  @memberof DataTable#oApi
6354.
     */
6355.
    function _fnLoadState ( settings, oInit, callback )
6356.
    {
6357.
        var i, ien;
6358.
        var columns = settings.aoColumns;
6359.
        var loaded = function ( s ) {
6360.
            if ( ! s || ! s.time ) {
6361.
                callback();
6362.
                return;
6363.
            }
6364.
    
6365.
            // Allow custom and plug-in manipulation functions to alter the saved data set and
6366.
            // cancelling of loading by returning false
6367.
            var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );
6368.
            if ( $.inArray( false, abStateLoad ) !== -1 ) {
6369.
                callback();
6370.
                return;
6371.
            }
6372.
    
6373.
            // Reject old data
6374.
            var duration = settings.iStateDuration;
6375.
            if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
6376.
                callback();
6377.
                return;
6378.
            }
6379.
    
6380.
            // Number of columns have changed - all bets are off, no restore of settings
6381.
            if ( s.columns && columns.length !== s.columns.length ) {
6382.
                callback();
6383.
                return;
6384.
            }
6385.
    
6386.
            // Store the saved state so it might be accessed at any time
6387.
            settings.oLoadedState = $.extend( true, {}, s );
6388.
    
6389.
            // Restore key features - todo - for 1.11 this needs to be done by
6390.
            // subscribed events
6391.
            if ( s.start !== undefined ) {
6392.
                settings._iDisplayStart    = s.start;
6393.
                settings.iInitDisplayStart = s.start;
6394.
            }
6395.
            if ( s.length !== undefined ) {
6396.
                settings._iDisplayLength   = s.length;
6397.
            }
6398.
    
6399.
            // Order
6400.
            if ( s.order !== undefined ) {
6401.
                settings.aaSorting = [];
6402.
                $.each( s.order, function ( i, col ) {
6403.
                    settings.aaSorting.push( col[0] >= columns.length ?
6404.
                        [ 0, col[1] ] :
6405.
                        col
6406.
                    );
6407.
                } );
6408.
            }
6409.
    
6410.
            // Search
6411.
            if ( s.search !== undefined ) {
6412.
                $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
6413.
            }
6414.
    
6415.
            // Columns
6416.
            //
6417.
            if ( s.columns ) {
6418.
                for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
6419.
                    var col = s.columns[i];
6420.
    
6421.
                    // Visibility
6422.
                    if ( col.visible !== undefined ) {
6423.
                        columns[i].bVisible = col.visible;
6424.
                    }
6425.
    
6426.
                    // Search
6427.
                    if ( col.search !== undefined ) {
6428.
                        $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
6429.
                    }
6430.
                }
6431.
            }
6432.
    
6433.
            _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
6434.
            callback();
6435.
        };
6436.
    
6437.
        if ( ! settings.oFeatures.bStateSave ) {
6438.
            callback();
6439.
            return;
6440.
        }
6441.
    
6442.
        var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
6443.
    
6444.
        if ( state !== undefined ) {
6445.
            loaded( state );
6446.
        }
6447.
        // otherwise, wait for the loaded callback to be executed
6448.
    }
6449.
    
6450.
    
6451.
    /**
6452.
     * Return the settings object for a particular table
6453.
     *  @param {node} table table we are using as a dataTable
6454.
     *  @returns {object} Settings object - or null if not found
6455.
     *  @memberof DataTable#oApi
6456.
     */
6457.
    function _fnSettingsFromNode ( table )
6458.
    {
6459.
        var settings = DataTable.settings;
6460.
        var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
6461.
    
6462.
        return idx !== -1 ?
6463.
            settings[ idx ] :
6464.
            null;
6465.
    }
6466.
    
6467.
    
6468.
    /**
6469.
     * Log an error message
6470.
     *  @param {object} settings dataTables settings object
6471.
     *  @param {int} level log error messages, or display them to the user
6472.
     *  @param {string} msg error message
6473.
     *  @param {int} tn Technical note id to get more information about the error.
6474.
     *  @memberof DataTable#oApi
6475.
     */
6476.
    function _fnLog( settings, level, msg, tn )
6477.
    {
6478.
        msg = 'DataTables warning: '+
6479.
            (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
6480.
    
6481.
        if ( tn ) {
6482.
            msg += '. For more information about this error, please see '+
6483.
            'http://datatables.net/tn/'+tn;
6484.
        }
6485.
    
6486.
        if ( ! level  ) {
6487.
            // Backwards compatibility pre 1.10
6488.
            var ext = DataTable.ext;
6489.
            var type = ext.sErrMode || ext.errMode;
6490.
    
6491.
            if ( settings ) {
6492.
                _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
6493.
            }
6494.
    
6495.
            if ( type == 'alert' ) {
6496.
                alert( msg );
6497.
            }
6498.
            else if ( type == 'throw' ) {
6499.
                throw new Error(msg);
6500.
            }
6501.
            else if ( typeof type == 'function' ) {
6502.
                type( settings, tn, msg );
6503.
            }
6504.
        }
6505.
        else if ( window.console && console.log ) {
6506.
            console.log( msg );
6507.
        }
6508.
    }
6509.
    
6510.
    
6511.
    /**
6512.
     * See if a property is defined on one object, if so assign it to the other object
6513.
     *  @param {object} ret target object
6514.
     *  @param {object} src source object
6515.
     *  @param {string} name property
6516.
     *  @param {string} [mappedName] name to map too - optional, name used if not given
6517.
     *  @memberof DataTable#oApi
6518.
     */
6519.
    function _fnMap( ret, src, name, mappedName )
6520.
    {
6521.
        if ( $.isArray( name ) ) {
6522.
            $.each( name, function (i, val) {
6523.
                if ( $.isArray( val ) ) {
6524.
                    _fnMap( ret, src, val[0], val[1] );
6525.
                }
6526.
                else {
6527.
                    _fnMap( ret, src, val );
6528.
                }
6529.
            } );
6530.
    
6531.
            return;
6532.
        }
6533.
    
6534.
        if ( mappedName === undefined ) {
6535.
            mappedName = name;
6536.
        }
6537.
    
6538.
        if ( src[name] !== undefined ) {
6539.
            ret[mappedName] = src[name];
6540.
        }
6541.
    }
6542.
    
6543.
    
6544.
    /**
6545.
     * Extend objects - very similar to jQuery.extend, but deep copy objects, and
6546.
     * shallow copy arrays. The reason we need to do this, is that we don't want to
6547.
     * deep copy array init values (such as aaSorting) since the dev wouldn't be
6548.
     * able to override them, but we do want to deep copy arrays.
6549.
     *  @param {object} out Object to extend
6550.
     *  @param {object} extender Object from which the properties will be applied to
6551.
     *      out
6552.
     *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
6553.
     *      independent copy with the exception of the `data` or `aaData` parameters
6554.
     *      if they are present. This is so you can pass in a collection to
6555.
     *      DataTables and have that used as your data source without breaking the
6556.
     *      references
6557.
     *  @returns {object} out Reference, just for convenience - out === the return.
6558.
     *  @memberof DataTable#oApi
6559.
     *  @todo This doesn't take account of arrays inside the deep copied objects.
6560.
     */
6561.
    function _fnExtend( out, extender, breakRefs )
6562.
    {
6563.
        var val;
6564.
    
6565.
        for ( var prop in extender ) {
6566.
            if ( extender.hasOwnProperty(prop) ) {
6567.
                val = extender[prop];
6568.
    
6569.
                if ( $.isPlainObject( val ) ) {
6570.
                    if ( ! $.isPlainObject( out[prop] ) ) {
6571.
                        out[prop] = {};
6572.
                    }
6573.
                    $.extend( true, out[prop], val );
6574.
                }
6575.
                else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
6576.
                    out[prop] = val.slice();
6577.
                }
6578.
                else {
6579.
                    out[prop] = val;
6580.
                }
6581.
            }
6582.
        }
6583.
    
6584.
        return out;
6585.
    }
6586.
    
6587.
    
6588.
    /**
6589.
     * Bind an event handers to allow a click or return key to activate the callback.
6590.
     * This is good for accessibility since a return on the keyboard will have the
6591.
     * same effect as a click, if the element has focus.
6592.
     *  @param {element} n Element to bind the action to
6593.
     *  @param {object} oData Data object to pass to the triggered function
6594.
     *  @param {function} fn Callback function for when the event is triggered
6595.
     *  @memberof DataTable#oApi
6596.
     */
6597.
    function _fnBindAction( n, oData, fn )
6598.
    {
6599.
        $(n)
6600.
            .on( 'click.DT', oData, function (e) {
6601.
                    $(n).trigger('blur'); // Remove focus outline for mouse users
6602.
                    fn(e);
6603.
                } )
6604.
            .on( 'keypress.DT', oData, function (e){
6605.
                    if ( e.which === 13 ) {
6606.
                        e.preventDefault();
6607.
                        fn(e);
6608.
                    }
6609.
                } )
6610.
            .on( 'selectstart.DT', function () {
6611.
                    /* Take the brutal approach to cancelling text selection */
6612.
                    return false;
6613.
                } );
6614.
    }
6615.
    
6616.
    
6617.
    /**
6618.
     * Register a callback function. Easily allows a callback function to be added to
6619.
     * an array store of callback functions that can then all be called together.
6620.
     *  @param {object} oSettings dataTables settings object
6621.
     *  @param {string} sStore Name of the array storage for the callbacks in oSettings
6622.
     *  @param {function} fn Function to be called back
6623.
     *  @param {string} sName Identifying name for the callback (i.e. a label)
6624.
     *  @memberof DataTable#oApi
6625.
     */
6626.
    function _fnCallbackReg( oSettings, sStore, fn, sName )
6627.
    {
6628.
        if ( fn )
6629.
        {
6630.
            oSettings[sStore].push( {
6631.
                "fn": fn,
6632.
                "sName": sName
6633.
            } );
6634.
        }
6635.
    }
6636.
    
6637.
    
6638.
    /**
6639.
     * Fire callback functions and trigger events. Note that the loop over the
6640.
     * callback array store is done backwards! Further note that you do not want to
6641.
     * fire off triggers in time sensitive applications (for example cell creation)
6642.
     * as its slow.
6643.
     *  @param {object} settings dataTables settings object
6644.
     *  @param {string} callbackArr Name of the array storage for the callbacks in
6645.
     *      oSettings
6646.
     *  @param {string} eventName Name of the jQuery custom event to trigger. If
6647.
     *      null no trigger is fired
6648.
     *  @param {array} args Array of arguments to pass to the callback function /
6649.
     *      trigger
6650.
     *  @memberof DataTable#oApi
6651.
     */
6652.
    function _fnCallbackFire( settings, callbackArr, eventName, args )
6653.
    {
6654.
        var ret = [];
6655.
    
6656.
        if ( callbackArr ) {
6657.
            ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
6658.
                return val.fn.apply( settings.oInstance, args );
6659.
            } );
6660.
        }
6661.
    
6662.
        if ( eventName !== null ) {
6663.
            var e = $.Event( eventName+'.dt' );
6664.
    
6665.
            $(settings.nTable).trigger( e, args );
6666.
    
6667.
            ret.push( e.result );
6668.
        }
6669.
    
6670.
        return ret;
6671.
    }
6672.
    
6673.
    
6674.
    function _fnLengthOverflow ( settings )
6675.
    {
6676.
        var
6677.
            start = settings._iDisplayStart,
6678.
            end = settings.fnDisplayEnd(),
6679.
            len = settings._iDisplayLength;
6680.
    
6681.
        /* If we have space to show extra rows (backing up from the end point - then do so */
6682.
        if ( start >= end )
6683.
        {
6684.
            start = end - len;
6685.
        }
6686.
    
6687.
        // Keep the start record on the current page
6688.
        start -= (start % len);
6689.
    
6690.
        if ( len === -1 || start < 0 )
6691.
        {
6692.
            start = 0;
6693.
        }
6694.
    
6695.
        settings._iDisplayStart = start;
6696.
    }
6697.
    
6698.
    
6699.
    function _fnRenderer( settings, type )
6700.
    {
6701.
        var renderer = settings.renderer;
6702.
        var host = DataTable.ext.renderer[type];
6703.
    
6704.
        if ( $.isPlainObject( renderer ) && renderer[type] ) {
6705.
            // Specific renderer for this type. If available use it, otherwise use
6706.
            // the default.
6707.
            return host[renderer[type]] || host._;
6708.
        }
6709.
        else if ( typeof renderer === 'string' ) {
6710.
            // Common renderer - if there is one available for this type use it,
6711.
            // otherwise use the default
6712.
            return host[renderer] || host._;
6713.
        }
6714.
    
6715.
        // Use the default
6716.
        return host._;
6717.
    }
6718.
    
6719.
    
6720.
    /**
6721.
     * Detect the data source being used for the table. Used to simplify the code
6722.
     * a little (ajax) and to make it compress a little smaller.
6723.
     *
6724.
     *  @param {object} settings dataTables settings object
6725.
     *  @returns {string} Data source
6726.
     *  @memberof DataTable#oApi
6727.
     */
6728.
    function _fnDataSource ( settings )
6729.
    {
6730.
        if ( settings.oFeatures.bServerSide ) {
6731.
            return 'ssp';
6732.
        }
6733.
        else if ( settings.ajax || settings.sAjaxSource ) {
6734.
            return 'ajax';
6735.
        }
6736.
        return 'dom';
6737.
    }
6738.
    
6739.
 
6740.
    
6741.
    
6742.
    /**
6743.
     * Computed structure of the DataTables API, defined by the options passed to
6744.
     * `DataTable.Api.register()` when building the API.
6745.
     *
6746.
     * The structure is built in order to speed creation and extension of the Api
6747.
     * objects since the extensions are effectively pre-parsed.
6748.
     *
6749.
     * The array is an array of objects with the following structure, where this
6750.
     * base array represents the Api prototype base:
6751.
     *
6752.
     *     [
6753.
     *       {
6754.
     *         name:      'data'                -- string   - Property name
6755.
     *         val:       function () {},       -- function - Api method (or undefined if just an object
6756.
     *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
6757.
     *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
6758.
     *       },
6759.
     *       {
6760.
     *         name:     'row'
6761.
     *         val:       {},
6762.
     *         methodExt: [ ... ],
6763.
     *         propExt:   [
6764.
     *           {
6765.
     *             name:      'data'
6766.
     *             val:       function () {},
6767.
     *             methodExt: [ ... ],
6768.
     *             propExt:   [ ... ]
6769.
     *           },
6770.
     *           ...
6771.
     *         ]
6772.
     *       }
6773.
     *     ]
6774.
     *
6775.
     * @type {Array}
6776.
     * @ignore
6777.
     */
6778.
    var __apiStruct = [];
6779.
    
6780.
    
6781.
    /**
6782.
     * `Array.prototype` reference.
6783.
     *
6784.
     * @type object
6785.
     * @ignore
6786.
     */
6787.
    var __arrayProto = Array.prototype;
6788.
    
6789.
    
6790.
    /**
6791.
     * Abstraction for `context` parameter of the `Api` constructor to allow it to
6792.
     * take several different forms for ease of use.
6793.
     *
6794.
     * Each of the input parameter types will be converted to a DataTables settings
6795.
     * object where possible.
6796.
     *
6797.
     * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
6798.
     *   of:
6799.
     *
6800.
     *   * `string` - jQuery selector. Any DataTables' matching the given selector
6801.
     *     with be found and used.
6802.
     *   * `node` - `TABLE` node which has already been formed into a DataTable.
6803.
     *   * `jQuery` - A jQuery object of `TABLE` nodes.
6804.
     *   * `object` - DataTables settings object
6805.
     *   * `DataTables.Api` - API instance
6806.
     * @return {array|null} Matching DataTables settings objects. `null` or
6807.
     *   `undefined` is returned if no matching DataTable is found.
6808.
     * @ignore
6809.
     */
6810.
    var _toSettings = function ( mixed )
6811.
    {
6812.
        var idx, jq;
6813.
        var settings = DataTable.settings;
6814.
        var tables = $.map( settings, function (el, i) {
6815.
            return el.nTable;
6816.
        } );
6817.
    
6818.
        if ( ! mixed ) {
6819.
            return [];
6820.
        }
6821.
        else if ( mixed.nTable && mixed.oApi ) {
6822.
            // DataTables settings object
6823.
            return [ mixed ];
6824.
        }
6825.
        else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6826.
            // Table node
6827.
            idx = $.inArray( mixed, tables );
6828.
            return idx !== -1 ? [ settings[idx] ] : null;
6829.
        }
6830.
        else if ( mixed && typeof mixed.settings === 'function' ) {
6831.
            return mixed.settings().toArray();
6832.
        }
6833.
        else if ( typeof mixed === 'string' ) {
6834.
            // jQuery selector
6835.
            jq = $(mixed);
6836.
        }
6837.
        else if ( mixed instanceof $ ) {
6838.
            // jQuery object (also DataTables instance)
6839.
            jq = mixed;
6840.
        }
6841.
    
6842.
        if ( jq ) {
6843.
            return jq.map( function(i) {
6844.
                idx = $.inArray( this, tables );
6845.
                return idx !== -1 ? settings[idx] : null;
6846.
            } ).toArray();
6847.
        }
6848.
    };
6849.
    
6850.
    
6851.
    /**
6852.
     * DataTables API class - used to control and interface with  one or more
6853.
     * DataTables enhanced tables.
6854.
     *
6855.
     * The API class is heavily based on jQuery, presenting a chainable interface
6856.
     * that you can use to interact with tables. Each instance of the API class has
6857.
     * a "context" - i.e. the tables that it will operate on. This could be a single
6858.
     * table, all tables on a page or a sub-set thereof.
6859.
     *
6860.
     * Additionally the API is designed to allow you to easily work with the data in
6861.
     * the tables, retrieving and manipulating it as required. This is done by
6862.
     * presenting the API class as an array like interface. The contents of the
6863.
     * array depend upon the actions requested by each method (for example
6864.
     * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6865.
     * return an array of objects or arrays depending upon your table's
6866.
     * configuration). The API object has a number of array like methods (`push`,
6867.
     * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6868.
     * `unique` etc) to assist your working with the data held in a table.
6869.
     *
6870.
     * Most methods (those which return an Api instance) are chainable, which means
6871.
     * the return from a method call also has all of the methods available that the
6872.
     * top level object had. For example, these two calls are equivalent:
6873.
     *
6874.
     *     // Not chained
6875.
     *     api.row.add( {...} );
6876.
     *     api.draw();
6877.
     *
6878.
     *     // Chained
6879.
     *     api.row.add( {...} ).draw();
6880.
     *
6881.
     * @class DataTable.Api
6882.
     * @param {array|object|string|jQuery} context DataTable identifier. This is
6883.
     *   used to define which DataTables enhanced tables this API will operate on.
6884.
     *   Can be one of:
6885.
     *
6886.
     *   * `string` - jQuery selector. Any DataTables' matching the given selector
6887.
     *     with be found and used.
6888.
     *   * `node` - `TABLE` node which has already been formed into a DataTable.
6889.
     *   * `jQuery` - A jQuery object of `TABLE` nodes.
6890.
     *   * `object` - DataTables settings object
6891.
     * @param {array} [data] Data to initialise the Api instance with.
6892.
     *
6893.
     * @example
6894.
     *   // Direct initialisation during DataTables construction
6895.
     *   var api = $('#example').DataTable();
6896.
     *
6897.
     * @example
6898.
     *   // Initialisation using a DataTables jQuery object
6899.
     *   var api = $('#example').dataTable().api();
6900.
     *
6901.
     * @example
6902.
     *   // Initialisation as a constructor
6903.
     *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
6904.
     */
6905.
    _Api = function ( context, data )
6906.
    {
6907.
        if ( ! (this instanceof _Api) ) {
6908.
            return new _Api( context, data );
6909.
        }
6910.
    
6911.
        var settings = [];
6912.
        var ctxSettings = function ( o ) {
6913.
            var a = _toSettings( o );
6914.
            if ( a ) {
6915.
                settings.push.apply( settings, a );
6916.
            }
6917.
        };
6918.
    
6919.
        if ( $.isArray( context ) ) {
6920.
            for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6921.
                ctxSettings( context[i] );
6922.
            }
6923.
        }
6924.
        else {
6925.
            ctxSettings( context );
6926.
        }
6927.
    
6928.
        // Remove duplicates
6929.
        this.context = _unique( settings );
6930.
    
6931.
        // Initial data
6932.
        if ( data ) {
6933.
            $.merge( this, data );
6934.
        }
6935.
    
6936.
        // selector
6937.
        this.selector = {
6938.
            rows: null,
6939.
            cols: null,
6940.
            opts: null
6941.
        };
6942.
    
6943.
        _Api.extend( this, this, __apiStruct );
6944.
    };
6945.
    
6946.
    DataTable.Api = _Api;
6947.
    
6948.
    // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6949.
    // isPlainObject.
6950.
    $.extend( _Api.prototype, {
6951.
        any: function ()
6952.
        {
6953.
            return this.count() !== 0;
6954.
        },
6955.
    
6956.
    
6957.
        concat:  __arrayProto.concat,
6958.
    
6959.
    
6960.
        context: [], // array of table settings objects
6961.
    
6962.
    
6963.
        count: function ()
6964.
        {
6965.
            return this.flatten().length;
6966.
        },
6967.
    
6968.
    
6969.
        each: function ( fn )
6970.
        {
6971.
            for ( var i=0, ien=this.length ; i<ien; i++ ) {
6972.
                fn.call( this, this[i], i, this );
6973.
            }
6974.
    
6975.
            return this;
6976.
        },
6977.
    
6978.
    
6979.
        eq: function ( idx )
6980.
        {
6981.
            var ctx = this.context;
6982.
    
6983.
            return ctx.length > idx ?
6984.
                new _Api( ctx[idx], this[idx] ) :
6985.
                null;
6986.
        },
6987.
    
6988.
    
6989.
        filter: function ( fn )
6990.
        {
6991.
            var a = [];
6992.
    
6993.
            if ( __arrayProto.filter ) {
6994.
                a = __arrayProto.filter.call( this, fn, this );
6995.
            }
6996.
            else {
6997.
                // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6998.
                for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6999.
                    if ( fn.call( this, this[i], i, this ) ) {
7000.
                        a.push( this[i] );
7001.
                    }
7002.
                }
7003.
            }
7004.
    
7005.
            return new _Api( this.context, a );
7006.
        },
7007.
    
7008.
    
7009.
        flatten: function ()
7010.
        {
7011.
            var a = [];
7012.
            return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
7013.
        },
7014.
    
7015.
    
7016.
        join:    __arrayProto.join,
7017.
    
7018.
    
7019.
        indexOf: __arrayProto.indexOf || function (obj, start)
7020.
        {
7021.
            for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
7022.
                if ( this[i] === obj ) {
7023.
                    return i;
7024.
                }
7025.
            }
7026.
            return -1;
7027.
        },
7028.
    
7029.
        iterator: function ( flatten, type, fn, alwaysNew ) {
7030.
            var
7031.
                a = [], ret,
7032.
                i, ien, j, jen,
7033.
                context = this.context,
7034.
                rows, items, item,
7035.
                selector = this.selector;
7036.
    
7037.
            // Argument shifting
7038.
            if ( typeof flatten === 'string' ) {
7039.
                alwaysNew = fn;
7040.
                fn = type;
7041.
                type = flatten;
7042.
                flatten = false;
7043.
            }
7044.
    
7045.
            for ( i=0, ien=context.length ; i<ien ; i++ ) {
7046.
                var apiInst = new _Api( context[i] );
7047.
    
7048.
                if ( type === 'table' ) {
7049.
                    ret = fn.call( apiInst, context[i], i );
7050.
    
7051.
                    if ( ret !== undefined ) {
7052.
                        a.push( ret );
7053.
                    }
7054.
                }
7055.
                else if ( type === 'columns' || type === 'rows' ) {
7056.
                    // this has same length as context - one entry for each table
7057.
                    ret = fn.call( apiInst, context[i], this[i], i );
7058.
    
7059.
                    if ( ret !== undefined ) {
7060.
                        a.push( ret );
7061.
                    }
7062.
                }
7063.
                else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
7064.
                    // columns and rows share the same structure.
7065.
                    // 'this' is an array of column indexes for each context
7066.
                    items = this[i];
7067.
    
7068.
                    if ( type === 'column-rows' ) {
7069.
                        rows = _selector_row_indexes( context[i], selector.opts );
7070.
                    }
7071.
    
7072.
                    for ( j=0, jen=items.length ; j<jen ; j++ ) {
7073.
                        item = items[j];
7074.
    
7075.
                        if ( type === 'cell' ) {
7076.
                            ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
7077.
                        }
7078.
                        else {
7079.
                            ret = fn.call( apiInst, context[i], item, i, j, rows );
7080.
                        }
7081.
    
7082.
                        if ( ret !== undefined ) {
7083.
                            a.push( ret );
7084.
                        }
7085.
                    }
7086.
                }
7087.
            }
7088.
    
7089.
            if ( a.length || alwaysNew ) {
7090.
                var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
7091.
                var apiSelector = api.selector;
7092.
                apiSelector.rows = selector.rows;
7093.
                apiSelector.cols = selector.cols;
7094.
                apiSelector.opts = selector.opts;
7095.
                return api;
7096.
            }
7097.
            return this;
7098.
        },
7099.
    
7100.
    
7101.
        lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
7102.
        {
7103.
            // Bit cheeky...
7104.
            return this.indexOf.apply( this.toArray.reverse(), arguments );
7105.
        },
7106.
    
7107.
    
7108.
        length:  0,
7109.
    
7110.
    
7111.
        map: function ( fn )
7112.
        {
7113.
            var a = [];
7114.
    
7115.
            if ( __arrayProto.map ) {
7116.
                a = __arrayProto.map.call( this, fn, this );
7117.
            }
7118.
            else {
7119.
                // Compatibility for browsers without EMCA-252-5 (JS 1.6)
7120.
                for ( var i=0, ien=this.length ; i<ien ; i++ ) {
7121.
                    a.push( fn.call( this, this[i], i ) );
7122.
                }
7123.
            }
7124.
    
7125.
            return new _Api( this.context, a );
7126.
        },
7127.
    
7128.
    
7129.
        pluck: function ( prop )
7130.
        {
7131.
            return this.map( function ( el ) {
7132.
                return el[ prop ];
7133.
            } );
7134.
        },
7135.
    
7136.
        pop:     __arrayProto.pop,
7137.
    
7138.
    
7139.
        push:    __arrayProto.push,
7140.
    
7141.
    
7142.
        // Does not return an API instance
7143.
        reduce: __arrayProto.reduce || function ( fn, init )
7144.
        {
7145.
            return _fnReduce( this, fn, init, 0, this.length, 1 );
7146.
        },
7147.
    
7148.
    
7149.
        reduceRight: __arrayProto.reduceRight || function ( fn, init )
7150.
        {
7151.
            return _fnReduce( this, fn, init, this.length-1, -1, -1 );
7152.
        },
7153.
    
7154.
    
7155.
        reverse: __arrayProto.reverse,
7156.
    
7157.
    
7158.
        // Object with rows, columns and opts
7159.
        selector: null,
7160.
    
7161.
    
7162.
        shift:   __arrayProto.shift,
7163.
    
7164.
    
7165.
        slice: function () {
7166.
            return new _Api( this.context, this );
7167.
        },
7168.
    
7169.
    
7170.
        sort:    __arrayProto.sort, // ? name - order?
7171.
    
7172.
    
7173.
        splice:  __arrayProto.splice,
7174.
    
7175.
    
7176.
        toArray: function ()
7177.
        {
7178.
            return __arrayProto.slice.call( this );
7179.
        },
7180.
    
7181.
    
7182.
        to$: function ()
7183.
        {
7184.
            return $( this );
7185.
        },
7186.
    
7187.
    
7188.
        toJQuery: function ()
7189.
        {
7190.
            return $( this );
7191.
        },
7192.
    
7193.
    
7194.
        unique: function ()
7195.
        {
7196.
            return new _Api( this.context, _unique(this) );
7197.
        },
7198.
    
7199.
    
7200.
        unshift: __arrayProto.unshift
7201.
    } );
7202.
    
7203.
    
7204.
    _Api.extend = function ( scope, obj, ext )
7205.
    {
7206.
        // Only extend API instances and static properties of the API
7207.
        if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7208.
            return;
7209.
        }
7210.
    
7211.
        var
7212.
            i, ien,
7213.
            struct,
7214.
            methodScoping = function ( scope, fn, struc ) {
7215.
                return function () {
7216.
                    var ret = fn.apply( scope, arguments );
7217.
    
7218.
                    // Method extension
7219.
                    _Api.extend( ret, ret, struc.methodExt );
7220.
                    return ret;
7221.
                };
7222.
            };
7223.
    
7224.
        for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7225.
            struct = ext[i];
7226.
    
7227.
            // Value
7228.
            obj[ struct.name ] = struct.type === 'function' ?
7229.
                methodScoping( scope, struct.val, struct ) :
7230.
                struct.type === 'object' ?
7231.
                    {} :
7232.
                    struct.val;
7233.
    
7234.
            obj[ struct.name ].__dt_wrapper = true;
7235.
    
7236.
            // Property extension
7237.
            _Api.extend( scope, obj[ struct.name ], struct.propExt );
7238.
        }
7239.
    };
7240.
    
7241.
    
7242.
    // @todo - Is there need for an augment function?
7243.
    // _Api.augment = function ( inst, name )
7244.
    // {
7245.
    //     // Find src object in the structure from the name
7246.
    //     var parts = name.split('.');
7247.
    
7248.
    //     _Api.extend( inst, obj );
7249.
    // };
7250.
    
7251.
    
7252.
    //     [
7253.
    //       {
7254.
    //         name:      'data'                -- string   - Property name
7255.
    //         val:       function () {},       -- function - Api method (or undefined if just an object
7256.
    //         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
7257.
    //         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
7258.
    //       },
7259.
    //       {
7260.
    //         name:     'row'
7261.
    //         val:       {},
7262.
    //         methodExt: [ ... ],
7263.
    //         propExt:   [
7264.
    //           {
7265.
    //             name:      'data'
7266.
    //             val:       function () {},
7267.
    //             methodExt: [ ... ],
7268.
    //             propExt:   [ ... ]
7269.
    //           },
7270.
    //           ...
7271.
    //         ]
7272.
    //       }
7273.
    //     ]
7274.
    
7275.
    _Api.register = _api_register = function ( name, val )
7276.
    {
7277.
        if ( $.isArray( name ) ) {
7278.
            for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7279.
                _Api.register( name[j], val );
7280.
            }
7281.
            return;
7282.
        }
7283.
    
7284.
        var
7285.
            i, ien,
7286.
            heir = name.split('.'),
7287.
            struct = __apiStruct,
7288.
            key, method;
7289.
    
7290.
        var find = function ( src, name ) {
7291.
            for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7292.
                if ( src[i].name === name ) {
7293.
                    return src[i];
7294.
                }
7295.
            }
7296.
            return null;
7297.
        };
7298.
    
7299.
        for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7300.
            method = heir[i].indexOf('()') !== -1;
7301.
            key = method ?
7302.
                heir[i].replace('()', '') :
7303.
                heir[i];
7304.
    
7305.
            var src = find( struct, key );
7306.
            if ( ! src ) {
7307.
                src = {
7308.
                    name:      key,
7309.
                    val:       {},
7310.
                    methodExt: [],
7311.
                    propExt:   [],
7312.
                    type:      'object'
7313.
                };
7314.
                struct.push( src );
7315.
            }
7316.
    
7317.
            if ( i === ien-1 ) {
7318.
                src.val = val;
7319.
                src.type = typeof val === 'function' ?
7320.
                    'function' :
7321.
                    $.isPlainObject( val ) ?
7322.
                        'object' :
7323.
                        'other';
7324.
            }
7325.
            else {
7326.
                struct = method ?
7327.
                    src.methodExt :
7328.
                    src.propExt;
7329.
            }
7330.
        }
7331.
    };
7332.
    
7333.
    _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7334.
        _Api.register( pluralName, val );
7335.
    
7336.
        _Api.register( singularName, function () {
7337.
            var ret = val.apply( this, arguments );
7338.
    
7339.
            if ( ret === this ) {
7340.
                // Returned item is the API instance that was passed in, return it
7341.
                return this;
7342.
            }
7343.
            else if ( ret instanceof _Api ) {
7344.
                // New API instance returned, want the value from the first item
7345.
                // in the returned array for the singular result.
7346.
                return ret.length ?
7347.
                    $.isArray( ret[0] ) ?
7348.
                        new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7349.
                        ret[0] :
7350.
                    undefined;
7351.
            }
7352.
    
7353.
            // Non-API return - just fire it back
7354.
            return ret;
7355.
        } );
7356.
    };
7357.
    
7358.
    
7359.
    /**
7360.
     * Selector for HTML tables. Apply the given selector to the give array of
7361.
     * DataTables settings objects.
7362.
     *
7363.
     * @param {string|integer} [selector] jQuery selector string or integer
7364.
     * @param  {array} Array of DataTables settings objects to be filtered
7365.
     * @return {array}
7366.
     * @ignore
7367.
     */
7368.
    var __table_selector = function ( selector, a )
7369.
    {
7370.
        if ( $.isArray(selector) ) {
7371.
            return $.map( selector, function (item) {
7372.
                return __table_selector(item, a);
7373.
            } );
7374.
        }
7375.
    
7376.
        // Integer is used to pick out a table by index
7377.
        if ( typeof selector === 'number' ) {
7378.
            return [ a[ selector ] ];
7379.
        }
7380.
    
7381.
        // Perform a jQuery selector on the table nodes
7382.
        var nodes = $.map( a, function (el, i) {
7383.
            return el.nTable;
7384.
        } );
7385.
    
7386.
        return $(nodes)
7387.
            .filter( selector )
7388.
            .map( function (i) {
7389.
                // Need to translate back from the table node to the settings
7390.
                var idx = $.inArray( this, nodes );
7391.
                return a[ idx ];
7392.
            } )
7393.
            .toArray();
7394.
    };
7395.
    
7396.
    
7397.
    
7398.
    /**
7399.
     * Context selector for the API's context (i.e. the tables the API instance
7400.
     * refers to.
7401.
     *
7402.
     * @name    DataTable.Api#tables
7403.
     * @param {string|integer} [selector] Selector to pick which tables the iterator
7404.
     *   should operate on. If not given, all tables in the current context are
7405.
     *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7406.
     *   select multiple tables or as an integer to select a single table.
7407.
     * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7408.
     */
7409.
    _api_register( 'tables()', function ( selector ) {
7410.
        // A new instance is created if there was a selector specified
7411.
        return selector !== undefined && selector !== null ?
7412.
            new _Api( __table_selector( selector, this.context ) ) :
7413.
            this;
7414.
    } );
7415.
    
7416.
    
7417.
    _api_register( 'table()', function ( selector ) {
7418.
        var tables = this.tables( selector );
7419.
        var ctx = tables.context;
7420.
    
7421.
        // Truncate to the first matched table
7422.
        return ctx.length ?
7423.
            new _Api( ctx[0] ) :
7424.
            tables;
7425.
    } );
7426.
    
7427.
    
7428.
    _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7429.
        return this.iterator( 'table', function ( ctx ) {
7430.
            return ctx.nTable;
7431.
        }, 1 );
7432.
    } );
7433.
    
7434.
    
7435.
    _api_registerPlural( 'tables().body()', 'table().body()' , function () {
7436.
        return this.iterator( 'table', function ( ctx ) {
7437.
            return ctx.nTBody;
7438.
        }, 1 );
7439.
    } );
7440.
    
7441.
    
7442.
    _api_registerPlural( 'tables().header()', 'table().header()' , function () {
7443.
        return this.iterator( 'table', function ( ctx ) {
7444.
            return ctx.nTHead;
7445.
        }, 1 );
7446.
    } );
7447.
    
7448.
    
7449.
    _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7450.
        return this.iterator( 'table', function ( ctx ) {
7451.
            return ctx.nTFoot;
7452.
        }, 1 );
7453.
    } );
7454.
    
7455.
    
7456.
    _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7457.
        return this.iterator( 'table', function ( ctx ) {
7458.
            return ctx.nTableWrapper;
7459.
        }, 1 );
7460.
    } );
7461.
    
7462.
    
7463.
    
7464.
    /**
7465.
     * Redraw the tables in the current context.
7466.
     */
7467.
    _api_register( 'draw()', function ( paging ) {
7468.
        return this.iterator( 'table', function ( settings ) {
7469.
            if ( paging === 'page' ) {
7470.
                _fnDraw( settings );
7471.
            }
7472.
            else {
7473.
                if ( typeof paging === 'string' ) {
7474.
                    paging = paging === 'full-hold' ?
7475.
                        false :
7476.
                        true;
7477.
                }
7478.
    
7479.
                _fnReDraw( settings, paging===false );
7480.
            }
7481.
        } );
7482.
    } );
7483.
    
7484.
    
7485.
    
7486.
    /**
7487.
     * Get the current page index.
7488.
     *
7489.
     * @return {integer} Current page index (zero based)
7490.
     *//**
7491.
     * Set the current page.
7492.
     *
7493.
     * Note that if you attempt to show a page which does not exist, DataTables will
7494.
     * not throw an error, but rather reset the paging.
7495.
     *
7496.
     * @param {integer|string} action The paging action to take. This can be one of:
7497.
     *  * `integer` - The page index to jump to
7498.
     *  * `string` - An action to take:
7499.
     *    * `first` - Jump to first page.
7500.
     *    * `next` - Jump to the next page
7501.
     *    * `previous` - Jump to previous page
7502.
     *    * `last` - Jump to the last page.
7503.
     * @returns {DataTables.Api} this
7504.
     */
7505.
    _api_register( 'page()', function ( action ) {
7506.
        if ( action === undefined ) {
7507.
            return this.page.info().page; // not an expensive call
7508.
        }
7509.
    
7510.
        // else, have an action to take on all tables
7511.
        return this.iterator( 'table', function ( settings ) {
7512.
            _fnPageChange( settings, action );
7513.
        } );
7514.
    } );
7515.
    
7516.
    
7517.
    /**
7518.
     * Paging information for the first table in the current context.
7519.
     *
7520.
     * If you require paging information for another table, use the `table()` method
7521.
     * with a suitable selector.
7522.
     *
7523.
     * @return {object} Object with the following properties set:
7524.
     *  * `page` - Current page index (zero based - i.e. the first page is `0`)
7525.
     *  * `pages` - Total number of pages
7526.
     *  * `start` - Display index for the first record shown on the current page
7527.
     *  * `end` - Display index for the last record shown on the current page
7528.
     *  * `length` - Display length (number of records). Note that generally `start
7529.
     *    + length = end`, but this is not always true, for example if there are
7530.
     *    only 2 records to show on the final page, with a length of 10.
7531.
     *  * `recordsTotal` - Full data set length
7532.
     *  * `recordsDisplay` - Data set length once the current filtering criterion
7533.
     *    are applied.
7534.
     */
7535.
    _api_register( 'page.info()', function ( action ) {
7536.
        if ( this.context.length === 0 ) {
7537.
            return undefined;
7538.
        }
7539.
    
7540.
        var
7541.
            settings   = this.context[0],
7542.
            start      = settings._iDisplayStart,
7543.
            len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
7544.
            visRecords = settings.fnRecordsDisplay(),
7545.
            all        = len === -1;
7546.
    
7547.
        return {
7548.
            "page":           all ? 0 : Math.floor( start / len ),
7549.
            "pages":          all ? 1 : Math.ceil( visRecords / len ),
7550.
            "start":          start,
7551.
            "end":            settings.fnDisplayEnd(),
7552.
            "length":         len,
7553.
            "recordsTotal":   settings.fnRecordsTotal(),
7554.
            "recordsDisplay": visRecords,
7555.
            "serverSide":     _fnDataSource( settings ) === 'ssp'
7556.
        };
7557.
    } );
7558.
    
7559.
    
7560.
    /**
7561.
     * Get the current page length.
7562.
     *
7563.
     * @return {integer} Current page length. Note `-1` indicates that all records
7564.
     *   are to be shown.
7565.
     *//**
7566.
     * Set the current page length.
7567.
     *
7568.
     * @param {integer} Page length to set. Use `-1` to show all records.
7569.
     * @returns {DataTables.Api} this
7570.
     */
7571.
    _api_register( 'page.len()', function ( len ) {
7572.
        // Note that we can't call this function 'length()' because `length`
7573.
        // is a Javascript property of functions which defines how many arguments
7574.
        // the function expects.
7575.
        if ( len === undefined ) {
7576.
            return this.context.length !== 0 ?
7577.
                this.context[0]._iDisplayLength :
7578.
                undefined;
7579.
        }
7580.
    
7581.
        // else, set the page length
7582.
        return this.iterator( 'table', function ( settings ) {
7583.
            _fnLengthChange( settings, len );
7584.
        } );
7585.
    } );
7586.
    
7587.
    
7588.
    
7589.
    var __reload = function ( settings, holdPosition, callback ) {
7590.
        // Use the draw event to trigger a callback
7591.
        if ( callback ) {
7592.
            var api = new _Api( settings );
7593.
    
7594.
            api.one( 'draw', function () {
7595.
                callback( api.ajax.json() );
7596.
            } );
7597.
        }
7598.
    
7599.
        if ( _fnDataSource( settings ) == 'ssp' ) {
7600.
            _fnReDraw( settings, holdPosition );
7601.
        }
7602.
        else {
7603.
            _fnProcessingDisplay( settings, true );
7604.
    
7605.
            // Cancel an existing request
7606.
            var xhr = settings.jqXHR;
7607.
            if ( xhr && xhr.readyState !== 4 ) {
7608.
                xhr.abort();
7609.
            }
7610.
    
7611.
            // Trigger xhr
7612.
            _fnBuildAjax( settings, [], function( json ) {
7613.
                _fnClearTable( settings );
7614.
    
7615.
                var data = _fnAjaxDataSrc( settings, json );
7616.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7617.
                    _fnAddData( settings, data[i] );
7618.
                }
7619.
    
7620.
                _fnReDraw( settings, holdPosition );
7621.
                _fnProcessingDisplay( settings, false );
7622.
            } );
7623.
        }
7624.
    };
7625.
    
7626.
    
7627.
    /**
7628.
     * Get the JSON response from the last Ajax request that DataTables made to the
7629.
     * server. Note that this returns the JSON from the first table in the current
7630.
     * context.
7631.
     *
7632.
     * @return {object} JSON received from the server.
7633.
     */
7634.
    _api_register( 'ajax.json()', function () {
7635.
        var ctx = this.context;
7636.
    
7637.
        if ( ctx.length > 0 ) {
7638.
            return ctx[0].json;
7639.
        }
7640.
    
7641.
        // else return undefined;
7642.
    } );
7643.
    
7644.
    
7645.
    /**
7646.
     * Get the data submitted in the last Ajax request
7647.
     */
7648.
    _api_register( 'ajax.params()', function () {
7649.
        var ctx = this.context;
7650.
    
7651.
        if ( ctx.length > 0 ) {
7652.
            return ctx[0].oAjaxData;
7653.
        }
7654.
    
7655.
        // else return undefined;
7656.
    } );
7657.
    
7658.
    
7659.
    /**
7660.
     * Reload tables from the Ajax data source. Note that this function will
7661.
     * automatically re-draw the table when the remote data has been loaded.
7662.
     *
7663.
     * @param {boolean} [reset=true] Reset (default) or hold the current paging
7664.
     *   position. A full re-sort and re-filter is performed when this method is
7665.
     *   called, which is why the pagination reset is the default action.
7666.
     * @returns {DataTables.Api} this
7667.
     */
7668.
    _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7669.
        return this.iterator( 'table', function (settings) {
7670.
            __reload( settings, resetPaging===false, callback );
7671.
        } );
7672.
    } );
7673.
    
7674.
    
7675.
    /**
7676.
     * Get the current Ajax URL. Note that this returns the URL from the first
7677.
     * table in the current context.
7678.
     *
7679.
     * @return {string} Current Ajax source URL
7680.
     *//**
7681.
     * Set the Ajax URL. Note that this will set the URL for all tables in the
7682.
     * current context.
7683.
     *
7684.
     * @param {string} url URL to set.
7685.
     * @returns {DataTables.Api} this
7686.
     */
7687.
    _api_register( 'ajax.url()', function ( url ) {
7688.
        var ctx = this.context;
7689.
    
7690.
        if ( url === undefined ) {
7691.
            // get
7692.
            if ( ctx.length === 0 ) {
7693.
                return undefined;
7694.
            }
7695.
            ctx = ctx[0];
7696.
    
7697.
            return ctx.ajax ?
7698.
                $.isPlainObject( ctx.ajax ) ?
7699.
                    ctx.ajax.url :
7700.
                    ctx.ajax :
7701.
                ctx.sAjaxSource;
7702.
        }
7703.
    
7704.
        // set
7705.
        return this.iterator( 'table', function ( settings ) {
7706.
            if ( $.isPlainObject( settings.ajax ) ) {
7707.
                settings.ajax.url = url;
7708.
            }
7709.
            else {
7710.
                settings.ajax = url;
7711.
            }
7712.
            // No need to consider sAjaxSource here since DataTables gives priority
7713.
            // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7714.
            // value of `sAjaxSource` redundant.
7715.
        } );
7716.
    } );
7717.
    
7718.
    
7719.
    /**
7720.
     * Load data from the newly set Ajax URL. Note that this method is only
7721.
     * available when `ajax.url()` is used to set a URL. Additionally, this method
7722.
     * has the same effect as calling `ajax.reload()` but is provided for
7723.
     * convenience when setting a new URL. Like `ajax.reload()` it will
7724.
     * automatically redraw the table once the remote data has been loaded.
7725.
     *
7726.
     * @returns {DataTables.Api} this
7727.
     */
7728.
    _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7729.
        // Same as a reload, but makes sense to present it for easy access after a
7730.
        // url change
7731.
        return this.iterator( 'table', function ( ctx ) {
7732.
            __reload( ctx, resetPaging===false, callback );
7733.
        } );
7734.
    } );
7735.
    
7736.
    
7737.
    
7738.
    
7739.
    var _selector_run = function ( type, selector, selectFn, settings, opts )
7740.
    {
7741.
        var
7742.
            out = [], res,
7743.
            a, i, ien, j, jen,
7744.
            selectorType = typeof selector;
7745.
    
7746.
        // Can't just check for isArray here, as an API or jQuery instance might be
7747.
        // given with their array like look
7748.
        if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7749.
            selector = [ selector ];
7750.
        }
7751.
    
7752.
        for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7753.
            // Only split on simple strings - complex expressions will be jQuery selectors
7754.
            a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
7755.
                selector[i].split(',') :
7756.
                [ selector[i] ];
7757.
    
7758.
            for ( j=0, jen=a.length ; j<jen ; j++ ) {
7759.
                res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7760.
    
7761.
                if ( res && res.length ) {
7762.
                    out = out.concat( res );
7763.
                }
7764.
            }
7765.
        }
7766.
    
7767.
        // selector extensions
7768.
        var ext = _ext.selector[ type ];
7769.
        if ( ext.length ) {
7770.
            for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7771.
                out = ext[i]( settings, opts, out );
7772.
            }
7773.
        }
7774.
    
7775.
        return _unique( out );
7776.
    };
7777.
    
7778.
    
7779.
    var _selector_opts = function ( opts )
7780.
    {
7781.
        if ( ! opts ) {
7782.
            opts = {};
7783.
        }
7784.
    
7785.
        // Backwards compatibility for 1.9- which used the terminology filter rather
7786.
        // than search
7787.
        if ( opts.filter && opts.search === undefined ) {
7788.
            opts.search = opts.filter;
7789.
        }
7790.
    
7791.
        return $.extend( {
7792.
            search: 'none',
7793.
            order: 'current',
7794.
            page: 'all'
7795.
        }, opts );
7796.
    };
7797.
    
7798.
    
7799.
    var _selector_first = function ( inst )
7800.
    {
7801.
        // Reduce the API instance to the first item found
7802.
        for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7803.
            if ( inst[i].length > 0 ) {
7804.
                // Assign the first element to the first item in the instance
7805.
                // and truncate the instance and context
7806.
                inst[0] = inst[i];
7807.
                inst[0].length = 1;
7808.
                inst.length = 1;
7809.
                inst.context = [ inst.context[i] ];
7810.
    
7811.
                return inst;
7812.
            }
7813.
        }
7814.
    
7815.
        // Not found - return an empty instance
7816.
        inst.length = 0;
7817.
        return inst;
7818.
    };
7819.
    
7820.
    
7821.
    var _selector_row_indexes = function ( settings, opts )
7822.
    {
7823.
        var
7824.
            i, ien, tmp, a=[],
7825.
            displayFiltered = settings.aiDisplay,
7826.
            displayMaster = settings.aiDisplayMaster;
7827.
    
7828.
        var
7829.
            search = opts.search,  // none, applied, removed
7830.
            order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
7831.
            page   = opts.page;    // all, current
7832.
    
7833.
        if ( _fnDataSource( settings ) == 'ssp' ) {
7834.
            // In server-side processing mode, most options are irrelevant since
7835.
            // rows not shown don't exist and the index order is the applied order
7836.
            // Removed is a special case - for consistency just return an empty
7837.
            // array
7838.
            return search === 'removed' ?
7839.
                [] :
7840.
                _range( 0, displayMaster.length );
7841.
        }
7842.
        else if ( page == 'current' ) {
7843.
            // Current page implies that order=current and fitler=applied, since it is
7844.
            // fairly senseless otherwise, regardless of what order and search actually
7845.
            // are
7846.
            for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7847.
                a.push( displayFiltered[i] );
7848.
            }
7849.
        }
7850.
        else if ( order == 'current' || order == 'applied' ) {
7851.
            if ( search == 'none') {
7852.
                a = displayMaster.slice();
7853.
            }
7854.
            else if ( search == 'applied' ) {
7855.
                a = displayFiltered.slice();
7856.
            }
7857.
            else if ( search == 'removed' ) {
7858.
                // O(n+m) solution by creating a hash map
7859.
                var displayFilteredMap = {};
7860.
    
7861.
                for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
7862.
                    displayFilteredMap[displayFiltered[i]] = null;
7863.
                }
7864.
    
7865.
                a = $.map( displayMaster, function (el) {
7866.
                    return ! displayFilteredMap.hasOwnProperty(el) ?
7867.
                        el :
7868.
                        null;
7869.
                } );
7870.
            }
7871.
        }
7872.
        else if ( order == 'index' || order == 'original' ) {
7873.
            for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7874.
                if ( search == 'none' ) {
7875.
                    a.push( i );
7876.
                }
7877.
                else { // applied | removed
7878.
                    tmp = $.inArray( i, displayFiltered );
7879.
    
7880.
                    if ((tmp === -1 && search == 'removed') ||
7881.
                        (tmp >= 0   && search == 'applied') )
7882.
                    {
7883.
                        a.push( i );
7884.
                    }
7885.
                }
7886.
            }
7887.
        }
7888.
    
7889.
        return a;
7890.
    };
7891.
    
7892.
    
7893.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7894.
     * Rows
7895.
     *
7896.
     * {}          - no selector - use all available rows
7897.
     * {integer}   - row aoData index
7898.
     * {node}      - TR node
7899.
     * {string}    - jQuery selector to apply to the TR elements
7900.
     * {array}     - jQuery array of nodes, or simply an array of TR nodes
7901.
     *
7902.
     */
7903.
    var __row_selector = function ( settings, selector, opts )
7904.
    {
7905.
        var rows;
7906.
        var run = function ( sel ) {
7907.
            var selInt = _intVal( sel );
7908.
            var i, ien;
7909.
            var aoData = settings.aoData;
7910.
    
7911.
            // Short cut - selector is a number and no options provided (default is
7912.
            // all records, so no need to check if the index is in there, since it
7913.
            // must be - dev error if the index doesn't exist).
7914.
            if ( selInt !== null && ! opts ) {
7915.
                return [ selInt ];
7916.
            }
7917.
    
7918.
            if ( ! rows ) {
7919.
                rows = _selector_row_indexes( settings, opts );
7920.
            }
7921.
    
7922.
            if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7923.
                // Selector - integer
7924.
                return [ selInt ];
7925.
            }
7926.
            else if ( sel === null || sel === undefined || sel === '' ) {
7927.
                // Selector - none
7928.
                return rows;
7929.
            }
7930.
    
7931.
            // Selector - function
7932.
            if ( typeof sel === 'function' ) {
7933.
                return $.map( rows, function (idx) {
7934.
                    var row = aoData[ idx ];
7935.
                    return sel( idx, row._aData, row.nTr ) ? idx : null;
7936.
                } );
7937.
            }
7938.
    
7939.
            // Selector - node
7940.
            if ( sel.nodeName ) {
7941.
                var rowIdx = sel._DT_RowIndex;  // Property added by DT for fast lookup
7942.
                var cellIdx = sel._DT_CellIndex;
7943.
    
7944.
                if ( rowIdx !== undefined ) {
7945.
                    // Make sure that the row is actually still present in the table
7946.
                    return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
7947.
                        [ rowIdx ] :
7948.
                        [];
7949.
                }
7950.
                else if ( cellIdx ) {
7951.
                    return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?
7952.
                        [ cellIdx.row ] :
7953.
                        [];
7954.
                }
7955.
                else {
7956.
                    var host = $(sel).closest('*[data-dt-row]');
7957.
                    return host.length ?
7958.
                        [ host.data('dt-row') ] :
7959.
                        [];
7960.
                }
7961.
            }
7962.
    
7963.
            // ID selector. Want to always be able to select rows by id, regardless
7964.
            // of if the tr element has been created or not, so can't rely upon
7965.
            // jQuery here - hence a custom implementation. This does not match
7966.
            // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7967.
            // but to select it using a CSS selector engine (like Sizzle or
7968.
            // querySelect) it would need to need to be escaped for some characters.
7969.
            // DataTables simplifies this for row selectors since you can select
7970.
            // only a row. A # indicates an id any anything that follows is the id -
7971.
            // unescaped.
7972.
            if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7973.
                // get row index from id
7974.
                var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7975.
                if ( rowObj !== undefined ) {
7976.
                    return [ rowObj.idx ];
7977.
                }
7978.
    
7979.
                // need to fall through to jQuery in case there is DOM id that
7980.
                // matches
7981.
            }
7982.
            
7983.
            // Get nodes in the order from the `rows` array with null values removed
7984.
            var nodes = _removeEmpty(
7985.
                _pluck_order( settings.aoData, rows, 'nTr' )
7986.
            );
7987.
    
7988.
            // Selector - jQuery selector string, array of nodes or jQuery object/
7989.
            // As jQuery's .filter() allows jQuery objects to be passed in filter,
7990.
            // it also allows arrays, so this will cope with all three options
7991.
            return $(nodes)
7992.
                .filter( sel )
7993.
                .map( function () {
7994.
                    return this._DT_RowIndex;
7995.
                } )
7996.
                .toArray();
7997.
        };
7998.
    
7999.
        return _selector_run( 'row', selector, run, settings, opts );
8000.
    };
8001.
    
8002.
    
8003.
    _api_register( 'rows()', function ( selector, opts ) {
8004.
        // argument shifting
8005.
        if ( selector === undefined ) {
8006.
            selector = '';
8007.
        }
8008.
        else if ( $.isPlainObject( selector ) ) {
8009.
            opts = selector;
8010.
            selector = '';
8011.
        }
8012.
    
8013.
        opts = _selector_opts( opts );
8014.
    
8015.
        var inst = this.iterator( 'table', function ( settings ) {
8016.
            return __row_selector( settings, selector, opts );
8017.
        }, 1 );
8018.
    
8019.
        // Want argument shifting here and in __row_selector?
8020.
        inst.selector.rows = selector;
8021.
        inst.selector.opts = opts;
8022.
    
8023.
        return inst;
8024.
    } );
8025.
    
8026.
    _api_register( 'rows().nodes()', function () {
8027.
        return this.iterator( 'row', function ( settings, row ) {
8028.
            return settings.aoData[ row ].nTr || undefined;
8029.
        }, 1 );
8030.
    } );
8031.
    
8032.
    _api_register( 'rows().data()', function () {
8033.
        return this.iterator( true, 'rows', function ( settings, rows ) {
8034.
            return _pluck_order( settings.aoData, rows, '_aData' );
8035.
        }, 1 );
8036.
    } );
8037.
    
8038.
    _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
8039.
        return this.iterator( 'row', function ( settings, row ) {
8040.
            var r = settings.aoData[ row ];
8041.
            return type === 'search' ? r._aFilterData : r._aSortData;
8042.
        }, 1 );
8043.
    } );
8044.
    
8045.
    _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
8046.
        return this.iterator( 'row', function ( settings, row ) {
8047.
            _fnInvalidate( settings, row, src );
8048.
        } );
8049.
    } );
8050.
    
8051.
    _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
8052.
        return this.iterator( 'row', function ( settings, row ) {
8053.
            return row;
8054.
        }, 1 );
8055.
    } );
8056.
    
8057.
    _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
8058.
        var a = [];
8059.
        var context = this.context;
8060.
    
8061.
        // `iterator` will drop undefined values, but in this case we want them
8062.
        for ( var i=0, ien=context.length ; i<ien ; i++ ) {
8063.
            for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
8064.
                var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
8065.
                a.push( (hash === true ? '#' : '' )+ id );
8066.
            }
8067.
        }
8068.
    
8069.
        return new _Api( context, a );
8070.
    } );
8071.
    
8072.
    _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
8073.
        var that = this;
8074.
    
8075.
        this.iterator( 'row', function ( settings, row, thatIdx ) {
8076.
            var data = settings.aoData;
8077.
            var rowData = data[ row ];
8078.
            var i, ien, j, jen;
8079.
            var loopRow, loopCells;
8080.
    
8081.
            data.splice( row, 1 );
8082.
    
8083.
            // Update the cached indexes
8084.
            for ( i=0, ien=data.length ; i<ien ; i++ ) {
8085.
                loopRow = data[i];
8086.
                loopCells = loopRow.anCells;
8087.
    
8088.
                // Rows
8089.
                if ( loopRow.nTr !== null ) {
8090.
                    loopRow.nTr._DT_RowIndex = i;
8091.
                }
8092.
    
8093.
                // Cells
8094.
                if ( loopCells !== null ) {
8095.
                    for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
8096.
                        loopCells[j]._DT_CellIndex.row = i;
8097.
                    }
8098.
                }
8099.
            }
8100.
    
8101.
            // Delete from the display arrays
8102.
            _fnDeleteIndex( settings.aiDisplayMaster, row );
8103.
            _fnDeleteIndex( settings.aiDisplay, row );
8104.
            _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
8105.
    
8106.
            // For server-side processing tables - subtract the deleted row from the count
8107.
            if ( settings._iRecordsDisplay > 0 ) {
8108.
                settings._iRecordsDisplay--;
8109.
            }
8110.
    
8111.
            // Check for an 'overflow' they case for displaying the table
8112.
            _fnLengthOverflow( settings );
8113.
    
8114.
            // Remove the row's ID reference if there is one
8115.
            var id = settings.rowIdFn( rowData._aData );
8116.
            if ( id !== undefined ) {
8117.
                delete settings.aIds[ id ];
8118.
            }
8119.
        } );
8120.
    
8121.
        this.iterator( 'table', function ( settings ) {
8122.
            for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
8123.
                settings.aoData[i].idx = i;
8124.
            }
8125.
        } );
8126.
    
8127.
        return this;
8128.
    } );
8129.
    
8130.
    
8131.
    _api_register( 'rows.add()', function ( rows ) {
8132.
        var newRows = this.iterator( 'table', function ( settings ) {
8133.
                var row, i, ien;
8134.
                var out = [];
8135.
    
8136.
                for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8137.
                    row = rows[i];
8138.
    
8139.
                    if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8140.
                        out.push( _fnAddTr( settings, row )[0] );
8141.
                    }
8142.
                    else {
8143.
                        out.push( _fnAddData( settings, row ) );
8144.
                    }
8145.
                }
8146.
    
8147.
                return out;
8148.
            }, 1 );
8149.
    
8150.
        // Return an Api.rows() extended instance, so rows().nodes() etc can be used
8151.
        var modRows = this.rows( -1 );
8152.
        modRows.pop();
8153.
        $.merge( modRows, newRows );
8154.
    
8155.
        return modRows;
8156.
    } );
8157.
    
8158.
    
8159.
    
8160.
    
8161.
    
8162.
    /**
8163.
     *
8164.
     */
8165.
    _api_register( 'row()', function ( selector, opts ) {
8166.
        return _selector_first( this.rows( selector, opts ) );
8167.
    } );
8168.
    
8169.
    
8170.
    _api_register( 'row().data()', function ( data ) {
8171.
        var ctx = this.context;
8172.
    
8173.
        if ( data === undefined ) {
8174.
            // Get
8175.
            return ctx.length && this.length ?
8176.
                ctx[0].aoData[ this[0] ]._aData :
8177.
                undefined;
8178.
        }
8179.
    
8180.
        // Set
8181.
        var row = ctx[0].aoData[ this[0] ];
8182.
        row._aData = data;
8183.
    
8184.
        // If the DOM has an id, and the data source is an array
8185.
        if ( $.isArray( data ) && row.nTr && row.nTr.id ) {
8186.
            _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
8187.
        }
8188.
    
8189.
        // Automatically invalidate
8190.
        _fnInvalidate( ctx[0], this[0], 'data' );
8191.
    
8192.
        return this;
8193.
    } );
8194.
    
8195.
    
8196.
    _api_register( 'row().node()', function () {
8197.
        var ctx = this.context;
8198.
    
8199.
        return ctx.length && this.length ?
8200.
            ctx[0].aoData[ this[0] ].nTr || null :
8201.
            null;
8202.
    } );
8203.
    
8204.
    
8205.
    _api_register( 'row.add()', function ( row ) {
8206.
        // Allow a jQuery object to be passed in - only a single row is added from
8207.
        // it though - the first element in the set
8208.
        if ( row instanceof $ && row.length ) {
8209.
            row = row[0];
8210.
        }
8211.
    
8212.
        var rows = this.iterator( 'table', function ( settings ) {
8213.
            if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8214.
                return _fnAddTr( settings, row )[0];
8215.
            }
8216.
            return _fnAddData( settings, row );
8217.
        } );
8218.
    
8219.
        // Return an Api.rows() extended instance, with the newly added row selected
8220.
        return this.row( rows[0] );
8221.
    } );
8222.
    
8223.
    
8224.
    
8225.
    var __details_add = function ( ctx, row, data, klass )
8226.
    {
8227.
        // Convert to array of TR elements
8228.
        var rows = [];
8229.
        var addRow = function ( r, k ) {
8230.
            // Recursion to allow for arrays of jQuery objects
8231.
            if ( $.isArray( r ) || r instanceof $ ) {
8232.
                for ( var i=0, ien=r.length ; i<ien ; i++ ) {
8233.
                    addRow( r[i], k );
8234.
                }
8235.
                return;
8236.
            }
8237.
    
8238.
            // If we get a TR element, then just add it directly - up to the dev
8239.
            // to add the correct number of columns etc
8240.
            if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
8241.
                rows.push( r );
8242.
            }
8243.
            else {
8244.
                // Otherwise create a row with a wrapper
8245.
                var created = $('<tr><td/></tr>').addClass( k );
8246.
                $('td', created)
8247.
                    .addClass( k )
8248.
                    .html( r )
8249.
                    [0].colSpan = _fnVisbleColumns( ctx );
8250.
    
8251.
                rows.push( created[0] );
8252.
            }
8253.
        };
8254.
    
8255.
        addRow( data, klass );
8256.
    
8257.
        if ( row._details ) {
8258.
            row._details.detach();
8259.
        }
8260.
    
8261.
        row._details = $(rows);
8262.
    
8263.
        // If the children were already shown, that state should be retained
8264.
        if ( row._detailsShow ) {
8265.
            row._details.insertAfter( row.nTr );
8266.
        }
8267.
    };
8268.
    
8269.
    
8270.
    var __details_remove = function ( api, idx )
8271.
    {
8272.
        var ctx = api.context;
8273.
    
8274.
        if ( ctx.length ) {
8275.
            var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8276.
    
8277.
            if ( row && row._details ) {
8278.
                row._details.remove();
8279.
    
8280.
                row._detailsShow = undefined;
8281.
                row._details = undefined;
8282.
            }
8283.
        }
8284.
    };
8285.
    
8286.
    
8287.
    var __details_display = function ( api, show ) {
8288.
        var ctx = api.context;
8289.
    
8290.
        if ( ctx.length && api.length ) {
8291.
            var row = ctx[0].aoData[ api[0] ];
8292.
    
8293.
            if ( row._details ) {
8294.
                row._detailsShow = show;
8295.
    
8296.
                if ( show ) {
8297.
                    row._details.insertAfter( row.nTr );
8298.
                }
8299.
                else {
8300.
                    row._details.detach();
8301.
                }
8302.
    
8303.
                __details_events( ctx[0] );
8304.
            }
8305.
        }
8306.
    };
8307.
    
8308.
    
8309.
    var __details_events = function ( settings )
8310.
    {
8311.
        var api = new _Api( settings );
8312.
        var namespace = '.dt.DT_details';
8313.
        var drawEvent = 'draw'+namespace;
8314.
        var colvisEvent = 'column-visibility'+namespace;
8315.
        var destroyEvent = 'destroy'+namespace;
8316.
        var data = settings.aoData;
8317.
    
8318.
        api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8319.
    
8320.
        if ( _pluck( data, '_details' ).length > 0 ) {
8321.
            // On each draw, insert the required elements into the document
8322.
            api.on( drawEvent, function ( e, ctx ) {
8323.
                if ( settings !== ctx ) {
8324.
                    return;
8325.
                }
8326.
    
8327.
                api.rows( {page:'current'} ).eq(0).each( function (idx) {
8328.
                    // Internal data grab
8329.
                    var row = data[ idx ];
8330.
    
8331.
                    if ( row._detailsShow ) {
8332.
                        row._details.insertAfter( row.nTr );
8333.
                    }
8334.
                } );
8335.
            } );
8336.
    
8337.
            // Column visibility change - update the colspan
8338.
            api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8339.
                if ( settings !== ctx ) {
8340.
                    return;
8341.
                }
8342.
    
8343.
                // Update the colspan for the details rows (note, only if it already has
8344.
                // a colspan)
8345.
                var row, visible = _fnVisbleColumns( ctx );
8346.
    
8347.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8348.
                    row = data[i];
8349.
    
8350.
                    if ( row._details ) {
8351.
                        row._details.children('td[colspan]').attr('colspan', visible );
8352.
                    }
8353.
                }
8354.
            } );
8355.
    
8356.
            // Table destroyed - nuke any child rows
8357.
            api.on( destroyEvent, function ( e, ctx ) {
8358.
                if ( settings !== ctx ) {
8359.
                    return;
8360.
                }
8361.
    
8362.
                for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8363.
                    if ( data[i]._details ) {
8364.
                        __details_remove( api, i );
8365.
                    }
8366.
                }
8367.
            } );
8368.
        }
8369.
    };
8370.
    
8371.
    // Strings for the method names to help minification
8372.
    var _emp = '';
8373.
    var _child_obj = _emp+'row().child';
8374.
    var _child_mth = _child_obj+'()';
8375.
    
8376.
    // data can be:
8377.
    //  tr
8378.
    //  string
8379.
    //  jQuery or array of any of the above
8380.
    _api_register( _child_mth, function ( data, klass ) {
8381.
        var ctx = this.context;
8382.
    
8383.
        if ( data === undefined ) {
8384.
            // get
8385.
            return ctx.length && this.length ?
8386.
                ctx[0].aoData[ this[0] ]._details :
8387.
                undefined;
8388.
        }
8389.
        else if ( data === true ) {
8390.
            // show
8391.
            this.child.show();
8392.
        }
8393.
        else if ( data === false ) {
8394.
            // remove
8395.
            __details_remove( this );
8396.
        }
8397.
        else if ( ctx.length && this.length ) {
8398.
            // set
8399.
            __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8400.
        }
8401.
    
8402.
        return this;
8403.
    } );
8404.
    
8405.
    
8406.
    _api_register( [
8407.
        _child_obj+'.show()',
8408.
        _child_mth+'.show()' // only when `child()` was called with parameters (without
8409.
    ], function ( show ) {   // it returns an object and this method is not executed)
8410.
        __details_display( this, true );
8411.
        return this;
8412.
    } );
8413.
    
8414.
    
8415.
    _api_register( [
8416.
        _child_obj+'.hide()',
8417.
        _child_mth+'.hide()' // only when `child()` was called with parameters (without
8418.
    ], function () {         // it returns an object and this method is not executed)
8419.
        __details_display( this, false );
8420.
        return this;
8421.
    } );
8422.
    
8423.
    
8424.
    _api_register( [
8425.
        _child_obj+'.remove()',
8426.
        _child_mth+'.remove()' // only when `child()` was called with parameters (without
8427.
    ], function () {           // it returns an object and this method is not executed)
8428.
        __details_remove( this );
8429.
        return this;
8430.
    } );
8431.
    
8432.
    
8433.
    _api_register( _child_obj+'.isShown()', function () {
8434.
        var ctx = this.context;
8435.
    
8436.
        if ( ctx.length && this.length ) {
8437.
            // _detailsShown as false or undefined will fall through to return false
8438.
            return ctx[0].aoData[ this[0] ]._detailsShow || false;
8439.
        }
8440.
        return false;
8441.
    } );
8442.
    
8443.
    
8444.
    
8445.
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8446.
     * Columns
8447.
     *
8448.
     * {integer}           - column index (>=0 count from left, <0 count from right)
8449.
     * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
8450.
     * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
8451.
     * "{string}:name"     - column name
8452.
     * "{string}"          - jQuery selector on column header nodes
8453.
     *
8454.
     */
8455.
    
8456.
    // can be an array of these items, comma separated list, or an array of comma
8457.
    // separated lists
8458.
    
8459.
    var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8460.
    
8461.
    
8462.
    // r1 and r2 are redundant - but it means that the parameters match for the
8463.
    // iterator callback in columns().data()
8464.
    var __columnData = function ( settings, column, r1, r2, rows ) {
8465.
        var a = [];
8466.
        for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8467.
            a.push( _fnGetCellData( settings, rows[row], column ) );
8468.
        }
8469.
        return a;
8470.
    };
8471.
    
8472.
    
8473.
    var __column_selector = function ( settings, selector, opts )
8474.
    {
8475.
        var
8476.
            columns = settings.aoColumns,
8477.
            names = _pluck( columns, 'sName' ),
8478.
            nodes = _pluck( columns, 'nTh' );
8479.
    
8480.
        var run = function ( s ) {
8481.
            var selInt = _intVal( s );
8482.
    
8483.
            // Selector - all
8484.
            if ( s === '' ) {
8485.
                return _range( columns.length );
8486.
            }
8487.
    
8488.
            // Selector - index
8489.
            if ( selInt !== null ) {
8490.
                return [ selInt >= 0 ?
8491.
                    selInt : // Count from left
8492.
                    columns.length + selInt // Count from right (+ because its a negative value)
8493.
                ];
8494.
            }
8495.
    
8496.
            // Selector = function
8497.
            if ( typeof s === 'function' ) {
8498.
                var rows = _selector_row_indexes( settings, opts );
8499.
    
8500.
                return $.map( columns, function (col, idx) {
8501.
                    return s(
8502.
                            idx,
8503.
                            __columnData( settings, idx, 0, 0, rows ),
8504.
                            nodes[ idx ]
8505.
                        ) ? idx : null;
8506.
                } );
8507.
            }
8508.
    
8509.
            // jQuery or string selector
8510.
            var match = typeof s === 'string' ?
8511.
                s.match( __re_column_selector ) :
8512.
                '';
8513.
    
8514.
            if ( match ) {
8515.
                switch( match[2] ) {
8516.
                    case 'visIdx':
8517.
                    case 'visible':
8518.
                        var idx = parseInt( match[1], 10 );
8519.
                        // Visible index given, convert to column index
8520.
                        if ( idx < 0 ) {
8521.
                            // Counting from the right
8522.
                            var visColumns = $.map( columns, function (col,i) {
8523.
                                return col.bVisible ? i : null;
8524.
                            } );
8525.
                            return [ visColumns[ visColumns.length + idx ] ];
8526.
                        }
8527.
                        // Counting from the left
8528.
                        return [ _fnVisibleToColumnIndex( settings, idx ) ];
8529.
    
8530.
                    case 'name':
8531.
                        // match by name. `names` is column index complete and in order
8532.
                        return $.map( names, function (name, i) {
8533.
                            return name === match[1] ? i : null;
8534.
                        } );
8535.
    
8536.
                    default:
8537.
                        return [];
8538.
                }
8539.
            }
8540.
    
8541.
            // Cell in the table body
8542.
            if ( s.nodeName && s._DT_CellIndex ) {
8543.
                return [ s._DT_CellIndex.column ];
8544.
            }
8545.
    
8546.
            // jQuery selector on the TH elements for the columns
8547.
            var jqResult = $( nodes )
8548.
                .filter( s )
8549.
                .map( function () {
8550.
                    return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8551.
                } )
8552.
                .toArray();
8553.
    
8554.
            if ( jqResult.length || ! s.nodeName ) {
8555.
                return jqResult;
8556.
            }
8557.
    
8558.
            // Otherwise a node which might have a `dt-column` data attribute, or be
8559.
            // a child or such an element
8560.
            var host = $(s).closest('*[data-dt-column]');
8561.
            return host.length ?
8562.
                [ host.data('dt-column') ] :
8563.
                [];
8564.
        };
8565.
    
8566.
        return _selector_run( 'column', selector, run, settings, opts );
8567.
    };
8568.
    
8569.
    
8570.
    var __setColumnVis = function ( settings, column, vis ) {
8571.
        var
8572.
            cols = settings.aoColumns,
8573.
            col  = cols[ column ],
8574.
            data = settings.aoData,
8575.
            row, cells, i, ien, tr;
8576.
    
8577.
        // Get
8578.
        if ( vis === undefined ) {
8579.
            return col.bVisible;
8580.
        }
8581.
    
8582.
        // Set
8583.
        // No change
8584.
        if ( col.bVisible === vis ) {
8585.
            return;
8586.
        }
8587.
    
8588.
        if ( vis ) {
8589.
            // Insert column
8590.
            // Need to decide if we should use appendChild or insertBefore
8591.
            var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8592.
    
8593.
            for ( i=0, ien=data.length ; i<ien ; i++ ) {
8594.
                tr = data[i].nTr;
8595.
                cells = data[i].anCells;
8596.
    
8597.
                if ( tr ) {
8598.
                    // insertBefore can act like appendChild if 2nd arg is null
8599.
                    tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8600.
                }
8601.
            }
8602.
        }
8603.
        else {
8604.
            // Remove column
8605.
            $( _pluck( settings.aoData, 'anCells', column ) ).detach();
8606.
        }
8607.
    
8608.
        // Common actions
8609.
        col.bVisible = vis;
8610.
    };
8611.
    
8612.
    
8613.
    _api_register( 'columns()', function ( selector, opts ) {
8614.
        // argument shifting
8615.
        if ( selector === undefined ) {
8616.
            selector = '';
8617.
        }
8618.
        else if ( $.isPlainObject( selector ) ) {
8619.
            opts = selector;
8620.
            selector = '';
8621.
        }
8622.
    
8623.
        opts = _selector_opts( opts );
8624.
    
8625.
        var inst = this.iterator( 'table', function ( settings ) {
8626.
            return __column_selector( settings, selector, opts );
8627.
        }, 1 );
8628.
    
8629.
        // Want argument shifting here and in _row_selector?
8630.
        inst.selector.cols = selector;
8631.
        inst.selector.opts = opts;
8632.
    
8633.
        return inst;
8634.
    } );
8635.
    
8636.
    _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8637.
        return this.iterator( 'column', function ( settings, column ) {
8638.
            return settings.aoColumns[column].nTh;
8639.
        }, 1 );
8640.
    } );
8641.
    
8642.
    _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8643.
        return this.iterator( 'column', function ( settings, column ) {
8644.
            return settings.aoColumns[column].nTf;
8645.
        }, 1 );
8646.
    } );
8647.
    
8648.
    _api_registerPlural( 'columns().data()', 'column().data()', function () {
8649.
        return this.iterator( 'column-rows', __columnData, 1 );
8650.
    } );
8651.
    
8652.
    _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8653.
        return this.iterator( 'column', function ( settings, column ) {
8654.
            return settings.aoColumns[column].mData;
8655.
        }, 1 );
8656.
    } );
8657.
    
8658.
    _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8659.
        return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8660.
            return _pluck_order( settings.aoData, rows,
8661.
                type === 'search' ? '_aFilterData' : '_aSortData', column
8662.
            );
8663.
        }, 1 );
8664.
    } );
8665.
    
8666.
    _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8667.
        return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8668.
            return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8669.
        }, 1 );
8670.
    } );
8671.
    
8672.
    _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8673.
        var that = this;
8674.
        var ret = this.iterator( 'column', function ( settings, column ) {
8675.
            if ( vis === undefined ) {
8676.
                return settings.aoColumns[ column ].bVisible;
8677.
            } // else
8678.
            __setColumnVis( settings, column, vis );
8679.
        } );
8680.
    
8681.
        // Group the column visibility changes
8682.
        if ( vis !== undefined ) {
8683.
            this.iterator( 'table', function ( settings ) {
8684.
                // Redraw the header after changes
8685.
                _fnDrawHead( settings, settings.aoHeader );
8686.
                _fnDrawHead( settings, settings.aoFooter );
8687.
        
8688.
                // Update colspan for no records display. Child rows and extensions will use their own
8689.
                // listeners to do this - only need to update the empty table item here
8690.
                if ( ! settings.aiDisplay.length ) {
8691.
                    $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
8692.
                }
8693.
        
8694.
                _fnSaveState( settings );
8695.
    
8696.
                // Second loop once the first is done for events
8697.
                that.iterator( 'column', function ( settings, column ) {
8698.
                    _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
8699.
                } );
8700.
    
8701.
                if ( calc === undefined || calc ) {
8702.
                    that.columns.adjust();
8703.
                }
8704.
            });
8705.
        }
8706.
    
8707.
        return ret;
8708.
    } );
8709.
    
8710.
    _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8711.
        return this.iterator( 'column', function ( settings, column ) {
8712.
            return type === 'visible' ?
8713.
                _fnColumnIndexToVisible( settings, column ) :
8714.
                column;
8715.
        }, 1 );
8716.
    } );
8717.
    
8718.
    _api_register( 'columns.adjust()', function () {
8719.
        return this.iterator( 'table', function ( settings ) {
8720.
            _fnAdjustColumnSizing( settings );
8721.
        }, 1 );
8722.
    } );
8723.
    
8724.
    _api_register( 'column.index()', function ( type, idx ) {
8725.
        if ( this.context.length !== 0 ) {
8726.
            var ctx = this.context[0];
8727.
    
8728.
            if ( type === 'fromVisible' || type === 'toData' ) {
8729.
                return _fnVisibleToColumnIndex( ctx, idx );
8730.
            }
8731.
            else if ( type === 'fromData' || type === 'toVisible' ) {
8732.
                return _fnColumnIndexToVisible( ctx, idx );
8733.
            }
8734.
        }
8735.
    } );
8736.
    
8737.
    _api_register( 'column()', function ( selector, opts ) {
8738.
        return _selector_first( this.columns( selector, opts ) );
8739.
    } );
8740.
    
8741.
    
8742.
    
8743.
    var __cell_selector = function ( settings, selector, opts )
8744.
    {
8745.
        var data = settings.aoData;
8746.
        var rows = _selector_row_indexes( settings, opts );
8747.
        var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8748.
        var allCells = $( [].concat.apply([], cells) );
8749.
        var row;
8750.
        var columns = settings.aoColumns.length;
8751.
        var a, i, ien, j, o, host;
8752.
    
8753.
        var run = function ( s ) {
8754.
            var fnSelector = typeof s === 'function';
8755.
    
8756.
            if ( s === null || s === undefined || fnSelector ) {
8757.
                // All cells and function selectors
8758.
                a = [];
8759.
    
8760.
                for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8761.
                    row = rows[i];
8762.
    
8763.
                    for ( j=0 ; j<columns ; j++ ) {
8764.
                        o = {
8765.
                            row: row,
8766.
                            column: j
8767.
                        };
8768.
    
8769.
                        if ( fnSelector ) {
8770.
                            // Selector - function
8771.
                            host = data[ row ];
8772.
    
8773.
                            if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8774.
                                a.push( o );
8775.
                            }
8776.
                        }
8777.
                        else {
8778.
                            // Selector - all
8779.
                            a.push( o );
8780.
                        }
8781.
                    }
8782.
                }
8783.
    
8784.
                return a;
8785.
            }
8786.
            
8787.
            // Selector - index
8788.
            if ( $.isPlainObject( s ) ) {
8789.
                // Valid cell index and its in the array of selectable rows
8790.
                return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
8791.
                    [s] :
8792.
                    [];
8793.
            }
8794.
    
8795.
            // Selector - jQuery filtered cells
8796.
            var jqResult = allCells
8797.
                .filter( s )
8798.
                .map( function (i, el) {
8799.
                    return { // use a new object, in case someone changes the values
8800.
                        row:    el._DT_CellIndex.row,
8801.
                        column: el._DT_CellIndex.column
8802.
                     };
8803.
                } )
8804.
                .toArray();
8805.
    
8806.
            if ( jqResult.length || ! s.nodeName ) {
8807.
                return jqResult;
8808.
            }
8809.
    
8810.
            // Otherwise the selector is a node, and there is one last option - the
8811.
            // element might be a child of an element which has dt-row and dt-column
8812.
            // data attributes
8813.
            host = $(s).closest('*[data-dt-row]');
8814.
            return host.length ?
8815.
                [ {
8816.
                    row: host.data('dt-row'),
8817.
                    column: host.data('dt-column')
8818.
                } ] :
8819.
                [];
8820.
        };
8821.
    
8822.
        return _selector_run( 'cell', selector, run, settings, opts );
8823.
    };
8824.
    
8825.
    
8826.
    
8827.
    
8828.
    _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8829.
        // Argument shifting
8830.
        if ( $.isPlainObject( rowSelector ) ) {
8831.
            // Indexes
8832.
            if ( rowSelector.row === undefined ) {
8833.
                // Selector options in first parameter
8834.
                opts = rowSelector;
8835.
                rowSelector = null;
8836.
            }
8837.
            else {
8838.
                // Cell index objects in first parameter
8839.
                opts = columnSelector;
8840.
                columnSelector = null;
8841.
            }
8842.
        }
8843.
        if ( $.isPlainObject( columnSelector ) ) {
8844.
            opts = columnSelector;
8845.
            columnSelector = null;
8846.
        }
8847.
    
8848.
        // Cell selector
8849.
        if ( columnSelector === null || columnSelector === undefined ) {
8850.
            return this.iterator( 'table', function ( settings ) {
8851.
                return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8852.
            } );
8853.
        }
8854.
    
8855.
        // The default built in options need to apply to row and columns
8856.
        var internalOpts = opts ? {
8857.
            page: opts.page,
8858.
            order: opts.order,
8859.
            search: opts.search
8860.
        } : {};
8861.
    
8862.
        // Row + column selector
8863.
        var columns = this.columns( columnSelector, internalOpts );
8864.
        var rows = this.rows( rowSelector, internalOpts );
8865.
        var i, ien, j, jen;
8866.
    
8867.
        var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
8868.
            var a = [];
8869.
    
8870.
            for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8871.
                for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8872.
                    a.push( {
8873.
                        row:    rows[idx][i],
8874.
                        column: columns[idx][j]
8875.
                    } );
8876.
                }
8877.
            }
8878.
    
8879.
            return a;
8880.
        }, 1 );
8881.
    
8882.
        // There is currently only one extension which uses a cell selector extension
8883.
        // It is a _major_ performance drag to run this if it isn't needed, so this is
8884.
        // an extension specific check at the moment
8885.
        var cells = opts && opts.selected ?
8886.
            this.cells( cellsNoOpts, opts ) :
8887.
            cellsNoOpts;
8888.
    
8889.
        $.extend( cells.selector, {
8890.
            cols: columnSelector,
8891.
            rows: rowSelector,
8892.
            opts: opts
8893.
        } );
8894.
    
8895.
        return cells;
8896.
    } );
8897.
    
8898.
    
8899.
    _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8900.
        return this.iterator( 'cell', function ( settings, row, column ) {
8901.
            var data = settings.aoData[ row ];
8902.
    
8903.
            return data && data.anCells ?
8904.
                data.anCells[ column ] :
8905.
                undefined;
8906.
        }, 1 );
8907.
    } );
8908.
    
8909.
    
8910.
    _api_register( 'cells().data()', function () {
8911.
        return this.iterator( 'cell', function ( settings, row, column ) {
8912.
            return _fnGetCellData( settings, row, column );
8913.
        }, 1 );
8914.
    } );
8915.
    
8916.
    
8917.
    _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8918.
        type = type === 'search' ? '_aFilterData' : '_aSortData';
8919.
    
8920.
        return this.iterator( 'cell', function ( settings, row, column ) {
8921.
            return settings.aoData[ row ][ type ][ column ];
8922.
        }, 1 );
8923.
    } );
8924.
    
8925.
    
8926.
    _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8927.
        return this.iterator( 'cell', function ( settings, row, column ) {
8928.
            return _fnGetCellData( settings, row, column, type );
8929.
        }, 1 );
8930.
    } );
8931.
    
8932.
    
8933.
    _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8934.
        return this.iterator( 'cell', function ( settings, row, column ) {
8935.
            return {
8936.
                row: row,
8937.
                column: column,
8938.
                columnVisible: _fnColumnIndexToVisible( settings, column )
8939.
            };
8940.
        }, 1 );
8941.
    } );
8942.
    
8943.
    
8944.
    _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8945.
        return this.iterator( 'cell', function ( settings, row, column ) {
8946.
            _fnInvalidate( settings, row, src, column );
8947.
        } );
8948.
    } );
8949.
    
8950.
    
8951.
    
8952.
    _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8953.
        return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8954.
    } );
8955.
    
8956.
    
8957.
    _api_register( 'cell().data()', function ( data ) {
8958.
        var ctx = this.context;
8959.
        var cell = this[0];
8960.
    
8961.
        if ( data === undefined ) {
8962.
            // Get
8963.
            return ctx.length && cell.length ?
8964.
                _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8965.
                undefined;
8966.
        }
8967.
    
8968.
        // Set
8969.
        _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8970.
        _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8971.
    
8972.
        return this;
8973.
    } );
8974.
    
8975.
    
8976.
    
8977.
    /**
8978.
     * Get current ordering (sorting) that has been applied to the table.
8979.
     *
8980.
     * @returns {array} 2D array containing the sorting information for the first
8981.
     *   table in the current context. Each element in the parent array represents
8982.
     *   a column being sorted upon (i.e. multi-sorting with two columns would have
8983.
     *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8984.
     *   the column index that the sorting condition applies to, the second is the
8985.
     *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
8986.
     *   index of the sorting order from the `column.sorting` initialisation array.
8987.
     *//**
8988.
     * Set the ordering for the table.
8989.
     *
8990.
     * @param {integer} order Column index to sort upon.
8991.
     * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8992.
     * @returns {DataTables.Api} this
8993.
     *//**
8994.
     * Set the ordering for the table.
8995.
     *
8996.
     * @param {array} order 1D array of sorting information to be applied.
8997.
     * @param {array} [...] Optional additional sorting conditions
8998.
     * @returns {DataTables.Api} this
8999.
     *//**
9000.
     * Set the ordering for the table.
9001.
     *
9002.
     * @param {array} order 2D array of sorting information to be applied.
9003.
     * @returns {DataTables.Api} this
9004.
     */
9005.
    _api_register( 'order()', function ( order, dir ) {
9006.
        var ctx = this.context;
9007.
    
9008.
        if ( order === undefined ) {
9009.
            // get
9010.
            return ctx.length !== 0 ?
9011.
                ctx[0].aaSorting :
9012.
                undefined;
9013.
        }
9014.
    
9015.
        // set
9016.
        if ( typeof order === 'number' ) {
9017.
            // Simple column / direction passed in
9018.
            order = [ [ order, dir ] ];
9019.
        }
9020.
        else if ( order.length && ! $.isArray( order[0] ) ) {
9021.
            // Arguments passed in (list of 1D arrays)
9022.
            order = Array.prototype.slice.call( arguments );
9023.
        }
9024.
        // otherwise a 2D array was passed in
9025.
    
9026.
        return this.iterator( 'table', function ( settings ) {
9027.
            settings.aaSorting = order.slice();
9028.
        } );
9029.
    } );
9030.
    
9031.
    
9032.
    /**
9033.
     * Attach a sort listener to an element for a given column
9034.
     *
9035.
     * @param {node|jQuery|string} node Identifier for the element(s) to attach the
9036.
     *   listener to. This can take the form of a single DOM node, a jQuery
9037.
     *   collection of nodes or a jQuery selector which will identify the node(s).
9038.
     * @param {integer} column the column that a click on this node will sort on
9039.
     * @param {function} [callback] callback function when sort is run
9040.
     * @returns {DataTables.Api} this
9041.
     */
9042.
    _api_register( 'order.listener()', function ( node, column, callback ) {
9043.
        return this.iterator( 'table', function ( settings ) {
9044.
            _fnSortAttachListener( settings, node, column, callback );
9045.
        } );
9046.
    } );
9047.
    
9048.
    
9049.
    _api_register( 'order.fixed()', function ( set ) {
9050.
        if ( ! set ) {
9051.
            var ctx = this.context;
9052.
            var fixed = ctx.length ?
9053.
                ctx[0].aaSortingFixed :
9054.
                undefined;
9055.
    
9056.
            return $.isArray( fixed ) ?
9057.
                { pre: fixed } :
9058.
                fixed;
9059.
        }
9060.
    
9061.
        return this.iterator( 'table', function ( settings ) {
9062.
            settings.aaSortingFixed = $.extend( true, {}, set );
9063.
        } );
9064.
    } );
9065.
    
9066.
    
9067.
    // Order by the selected column(s)
9068.
    _api_register( [
9069.
        'columns().order()',
9070.
        'column().order()'
9071.
    ], function ( dir ) {
9072.
        var that = this;
9073.
    
9074.
        return this.iterator( 'table', function ( settings, i ) {
9075.
            var sort = [];
9076.
    
9077.
            $.each( that[i], function (j, col) {
9078.
                sort.push( [ col, dir ] );
9079.
            } );
9080.
    
9081.
            settings.aaSorting = sort;
9082.
        } );
9083.
    } );
9084.
    
9085.
    
9086.
    
9087.
    _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
9088.
        var ctx = this.context;
9089.
    
9090.
        if ( input === undefined ) {
9091.
            // get
9092.
            return ctx.length !== 0 ?
9093.
                ctx[0].oPreviousSearch.sSearch :
9094.
                undefined;
9095.
        }
9096.
    
9097.
        // set
9098.
        return this.iterator( 'table', function ( settings ) {
9099.
            if ( ! settings.oFeatures.bFilter ) {
9100.
                return;
9101.
            }
9102.
    
9103.
            _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
9104.
                "sSearch": input+"",
9105.
                "bRegex":  regex === null ? false : regex,
9106.
                "bSmart":  smart === null ? true  : smart,
9107.
                "bCaseInsensitive": caseInsen === null ? true : caseInsen
9108.
            } ), 1 );
9109.
        } );
9110.
    } );
9111.
    
9112.
    
9113.
    _api_registerPlural(
9114.
        'columns().search()',
9115.
        'column().search()',
9116.
        function ( input, regex, smart, caseInsen ) {
9117.
            return this.iterator( 'column', function ( settings, column ) {
9118.
                var preSearch = settings.aoPreSearchCols;
9119.
    
9120.
                if ( input === undefined ) {
9121.
                    // get
9122.
                    return preSearch[ column ].sSearch;
9123.
                }
9124.
    
9125.
                // set
9126.
                if ( ! settings.oFeatures.bFilter ) {
9127.
                    return;
9128.
                }
9129.
    
9130.
                $.extend( preSearch[ column ], {
9131.
                    "sSearch": input+"",
9132.
                    "bRegex":  regex === null ? false : regex,
9133.
                    "bSmart":  smart === null ? true  : smart,
9134.
                    "bCaseInsensitive": caseInsen === null ? true : caseInsen
9135.
                } );
9136.
    
9137.
                _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
9138.
            } );
9139.
        }
9140.
    );
9141.
    
9142.
    /*
9143.
     * State API methods
9144.
     */
9145.
    
9146.
    _api_register( 'state()', function () {
9147.
        return this.context.length ?
9148.
            this.context[0].oSavedState :
9149.
            null;
9150.
    } );
9151.
    
9152.
    
9153.
    _api_register( 'state.clear()', function () {
9154.
        return this.iterator( 'table', function ( settings ) {
9155.
            // Save an empty object
9156.
            settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
9157.
        } );
9158.
    } );
9159.
    
9160.
    
9161.
    _api_register( 'state.loaded()', function () {
9162.
        return this.context.length ?
9163.
            this.context[0].oLoadedState :
9164.
            null;
9165.
    } );
9166.
    
9167.
    
9168.
    _api_register( 'state.save()', function () {
9169.
        return this.iterator( 'table', function ( settings ) {
9170.
            _fnSaveState( settings );
9171.
        } );
9172.
    } );
9173.
    
9174.
    
9175.
    
9176.
    /**
9177.
     * Provide a common method for plug-ins to check the version of DataTables being
9178.
     * used, in order to ensure compatibility.
9179.
     *
9180.
     *  @param {string} version Version string to check for, in the format "X.Y.Z".
9181.
     *    Note that the formats "X" and "X.Y" are also acceptable.
9182.
     *  @returns {boolean} true if this version of DataTables is greater or equal to
9183.
     *    the required version, or false if this version of DataTales is not
9184.
     *    suitable
9185.
     *  @static
9186.
     *  @dtopt API-Static
9187.
     *
9188.
     *  @example
9189.
     *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
9190.
     */
9191.
    DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
9192.
    {
9193.
        var aThis = DataTable.version.split('.');
9194.
        var aThat = version.split('.');
9195.
        var iThis, iThat;
9196.
    
9197.
        for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
9198.
            iThis = parseInt( aThis[i], 10 ) || 0;
9199.
            iThat = parseInt( aThat[i], 10 ) || 0;
9200.
    
9201.
            // Parts are the same, keep comparing
9202.
            if (iThis === iThat) {
9203.
                continue;
9204.
            }
9205.
    
9206.
            // Parts are different, return immediately
9207.
            return iThis > iThat;
9208.
        }
9209.
    
9210.
        return true;
9211.
    };
9212.
    
9213.
    
9214.
    /**
9215.
     * Check if a `<table>` node is a DataTable table already or not.
9216.
     *
9217.
     *  @param {node|jquery|string} table Table node, jQuery object or jQuery
9218.
     *      selector for the table to test. Note that if more than more than one
9219.
     *      table is passed on, only the first will be checked
9220.
     *  @returns {boolean} true the table given is a DataTable, or false otherwise
9221.
     *  @static
9222.
     *  @dtopt API-Static
9223.
     *
9224.
     *  @example
9225.
     *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
9226.
     *      $('#example').dataTable();
9227.
     *    }
9228.
     */
9229.
    DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
9230.
    {
9231.
        var t = $(table).get(0);
9232.
        var is = false;
9233.
    
9234.
        if ( table instanceof DataTable.Api ) {
9235.
            return true;
9236.
        }
9237.
    
9238.
        $.each( DataTable.settings, function (i, o) {
9239.
            var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
9240.
            var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
9241.
    
9242.
            if ( o.nTable === t || head === t || foot === t ) {
9243.
                is = true;
9244.
            }
9245.
        } );
9246.
    
9247.
        return is;
9248.
    };
9249.
    
9250.
    
9251.
    /**
9252.
     * Get all DataTable tables that have been initialised - optionally you can
9253.
     * select to get only currently visible tables.
9254.
     *
9255.
     *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
9256.
     *    or visible tables only.
9257.
     *  @returns {array} Array of `table` nodes (not DataTable instances) which are
9258.
     *    DataTables
9259.
     *  @static
9260.
     *  @dtopt API-Static
9261.
     *
9262.
     *  @example
9263.
     *    $.each( $.fn.dataTable.tables(true), function () {
9264.
     *      $(table).DataTable().columns.adjust();
9265.
     *    } );
9266.
     */
9267.
    DataTable.tables = DataTable.fnTables = function ( visible )
9268.
    {
9269.
        var api = false;
9270.
    
9271.
        if ( $.isPlainObject( visible ) ) {
9272.
            api = visible.api;
9273.
            visible = visible.visible;
9274.
        }
9275.
    
9276.
        var a = $.map( DataTable.settings, function (o) {
9277.
            if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
9278.
                return o.nTable;
9279.
            }
9280.
        } );
9281.
    
9282.
        return api ?
9283.
            new _Api( a ) :
9284.
            a;
9285.
    };
9286.
    
9287.
    
9288.
    /**
9289.
     * Convert from camel case parameters to Hungarian notation. This is made public
9290.
     * for the extensions to provide the same ability as DataTables core to accept
9291.
     * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9292.
     * parameters.
9293.
     *
9294.
     *  @param {object} src The model object which holds all parameters that can be
9295.
     *    mapped.
9296.
     *  @param {object} user The object to convert from camel case to Hungarian.
9297.
     *  @param {boolean} force When set to `true`, properties which already have a
9298.
     *    Hungarian value in the `user` object will be overwritten. Otherwise they
9299.
     *    won't be.
9300.
     */
9301.
    DataTable.camelToHungarian = _fnCamelToHungarian;
9302.
    
9303.
    
9304.
    
9305.
    /**
9306.
     *
9307.
     */
9308.
    _api_register( '$()', function ( selector, opts ) {
9309.
        var
9310.
            rows   = this.rows( opts ).nodes(), // Get all rows
9311.
            jqRows = $(rows);
9312.
    
9313.
        return $( [].concat(
9314.
            jqRows.filter( selector ).toArray(),
9315.
            jqRows.find( selector ).toArray()
9316.
        ) );
9317.
    } );
9318.
    
9319.
    
9320.
    // jQuery functions to operate on the tables
9321.
    $.each( [ 'on', 'one', 'off' ], function (i, key) {
9322.
        _api_register( key+'()', function ( /* event, handler */ ) {
9323.
            var args = Array.prototype.slice.call(arguments);
9324.
    
9325.
            // Add the `dt` namespace automatically if it isn't already present
9326.
            args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
9327.
                return ! e.match(/\.dt\b/) ?
9328.
                    e+'.dt' :
9329.
                    e;
9330.
                } ).join( ' ' );
9331.
    
9332.
            var inst = $( this.tables().nodes() );
9333.
            inst[key].apply( inst, args );
9334.
            return this;
9335.
        } );
9336.
    } );
9337.
    
9338.
    
9339.
    _api_register( 'clear()', function () {
9340.
        return this.iterator( 'table', function ( settings ) {
9341.
            _fnClearTable( settings );
9342.
        } );
9343.
    } );
9344.
    
9345.
    
9346.
    _api_register( 'settings()', function () {
9347.
        return new _Api( this.context, this.context );
9348.
    } );
9349.
    
9350.
    
9351.
    _api_register( 'init()', function () {
9352.
        var ctx = this.context;
9353.
        return ctx.length ? ctx[0].oInit : null;
9354.
    } );
9355.
    
9356.
    
9357.
    _api_register( 'data()', function () {
9358.
        return this.iterator( 'table', function ( settings ) {
9359.
            return _pluck( settings.aoData, '_aData' );
9360.
        } ).flatten();
9361.
    } );
9362.
    
9363.
    
9364.
    _api_register( 'destroy()', function ( remove ) {
9365.
        remove = remove || false;
9366.
    
9367.
        return this.iterator( 'table', function ( settings ) {
9368.
            var orig      = settings.nTableWrapper.parentNode;
9369.
            var classes   = settings.oClasses;
9370.
            var table     = settings.nTable;
9371.
            var tbody     = settings.nTBody;
9372.
            var thead     = settings.nTHead;
9373.
            var tfoot     = settings.nTFoot;
9374.
            var jqTable   = $(table);
9375.
            var jqTbody   = $(tbody);
9376.
            var jqWrapper = $(settings.nTableWrapper);
9377.
            var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
9378.
            var i, ien;
9379.
    
9380.
            // Flag to note that the table is currently being destroyed - no action
9381.
            // should be taken
9382.
            settings.bDestroying = true;
9383.
    
9384.
            // Fire off the destroy callbacks for plug-ins etc
9385.
            _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9386.
    
9387.
            // If not being removed from the document, make all columns visible
9388.
            if ( ! remove ) {
9389.
                new _Api( settings ).columns().visible( true );
9390.
            }
9391.
    
9392.
            // Blitz all `DT` namespaced events (these are internal events, the
9393.
            // lowercase, `dt` events are user subscribed and they are responsible
9394.
            // for removing them
9395.
            jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9396.
            $(window).off('.DT-'+settings.sInstance);
9397.
    
9398.
            // When scrolling we had to break the table up - restore it
9399.
            if ( table != thead.parentNode ) {
9400.
                jqTable.children('thead').detach();
9401.
                jqTable.append( thead );
9402.
            }
9403.
    
9404.
            if ( tfoot && table != tfoot.parentNode ) {
9405.
                jqTable.children('tfoot').detach();
9406.
                jqTable.append( tfoot );
9407.
            }
9408.
    
9409.
            settings.aaSorting = [];
9410.
            settings.aaSortingFixed = [];
9411.
            _fnSortingClasses( settings );
9412.
    
9413.
            $( rows ).removeClass( settings.asStripeClasses.join(' ') );
9414.
    
9415.
            $('th, td', thead).removeClass( classes.sSortable+' '+
9416.
                classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9417.
            );
9418.
    
9419.
            // Add the TR elements back into the table in their original order
9420.
            jqTbody.children().detach();
9421.
            jqTbody.append( rows );
9422.
    
9423.
            // Remove the DataTables generated nodes, events and classes
9424.
            var removedMethod = remove ? 'remove' : 'detach';
9425.
            jqTable[ removedMethod ]();
9426.
            jqWrapper[ removedMethod ]();
9427.
    
9428.
            // If we need to reattach the table to the document
9429.
            if ( ! remove && orig ) {
9430.
                // insertBefore acts like appendChild if !arg[1]
9431.
                orig.insertBefore( table, settings.nTableReinsertBefore );
9432.
    
9433.
                // Restore the width of the original table - was read from the style property,
9434.
                // so we can restore directly to that
9435.
                jqTable
9436.
                    .css( 'width', settings.sDestroyWidth )
9437.
                    .removeClass( classes.sTable );
9438.
    
9439.
                // If the were originally stripe classes - then we add them back here.
9440.
                // Note this is not fool proof (for example if not all rows had stripe
9441.
                // classes - but it's a good effort without getting carried away
9442.
                ien = settings.asDestroyStripes.length;
9443.
    
9444.
                if ( ien ) {
9445.
                    jqTbody.children().each( function (i) {
9446.
                        $(this).addClass( settings.asDestroyStripes[i % ien] );
9447.
                    } );
9448.
                }
9449.
            }
9450.
    
9451.
            /* Remove the settings object from the settings array */
9452.
            var idx = $.inArray( settings, DataTable.settings );
9453.
            if ( idx !== -1 ) {
9454.
                DataTable.settings.splice( idx, 1 );
9455.
            }
9456.
        } );
9457.
    } );
9458.
    
9459.
    
9460.
    // Add the `every()` method for rows, columns and cells in a compact form
9461.
    $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9462.
        _api_register( type+'s().every()', function ( fn ) {
9463.
            var opts = this.selector.opts;
9464.
            var api = this;
9465.
    
9466.
            return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9467.
                // Rows and columns:
9468.
                //  arg1 - index
9469.
                //  arg2 - table counter
9470.
                //  arg3 - loop counter
9471.
                //  arg4 - undefined
9472.
                // Cells:
9473.
                //  arg1 - row index
9474.
                //  arg2 - column index
9475.
                //  arg3 - table counter
9476.
                //  arg4 - loop counter
9477.
                fn.call(
9478.
                    api[ type ](
9479.
                        arg1,
9480.
                        type==='cell' ? arg2 : opts,
9481.
                        type==='cell' ? opts : undefined
9482.
                    ),
9483.
                    arg1, arg2, arg3, arg4
9484.
                );
9485.
            } );
9486.
        } );
9487.
    } );
9488.
    
9489.
    
9490.
    // i18n method for extensions to be able to use the language object from the
9491.
    // DataTable
9492.
    _api_register( 'i18n()', function ( token, def, plural ) {
9493.
        var ctx = this.context[0];
9494.
        var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9495.
    
9496.
        if ( resolved === undefined ) {
9497.
            resolved = def;
9498.
        }
9499.
    
9500.
        if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9501.
            resolved = resolved[ plural ] !== undefined ?
9502.
                resolved[ plural ] :
9503.
                resolved._;
9504.
        }
9505.
    
9506.
        return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9507.
    } );
9508.
    /**
9509.
     * Version string for plug-ins to check compatibility. Allowed format is
9510.
     * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9511.
     * only for non-release builds. See http://semver.org/ for more information.
9512.
     *  @member
9513.
     *  @type string
9514.
     *  @default Version number
9515.
     */
9516.
    DataTable.version = "1.10.21";
9517.
 
9518.
    /**
9519.
     * Private data store, containing all of the settings objects that are
9520.
     * created for the tables on a given page.
9521.
     *
9522.
     * Note that the `DataTable.settings` object is aliased to
9523.
     * `jQuery.fn.dataTableExt` through which it may be accessed and
9524.
     * manipulated, or `jQuery.fn.dataTable.settings`.
9525.
     *  @member
9526.
     *  @type array
9527.
     *  @default []
9528.
     *  @private
9529.
     */
9530.
    DataTable.settings = [];
9531.
 
9532.
    /**
9533.
     * Object models container, for the various models that DataTables has
9534.
     * available to it. These models define the objects that are used to hold
9535.
     * the active state and configuration of the table.
9536.
     *  @namespace
9537.
     */
9538.
    DataTable.models = {};
9539.
    
9540.
    
9541.
    
9542.
    /**
9543.
     * Template object for the way in which DataTables holds information about
9544.
     * search information for the global filter and individual column filters.
9545.
     *  @namespace
9546.
     */
9547.
    DataTable.models.oSearch = {
9548.
        /**
9549.
         * Flag to indicate if the filtering should be case insensitive or not
9550.
         *  @type boolean
9551.
         *  @default true
9552.
         */
9553.
        "bCaseInsensitive": true,
9554.
    
9555.
        /**
9556.
         * Applied search term
9557.
         *  @type string
9558.
         *  @default <i>Empty string</i>
9559.
         */
9560.
        "sSearch": "",
9561.
    
9562.
        /**
9563.
         * Flag to indicate if the search term should be interpreted as a
9564.
         * regular expression (true) or not (false) and therefore and special
9565.
         * regex characters escaped.
9566.
         *  @type boolean
9567.
         *  @default false
9568.
         */
9569.
        "bRegex": false,
9570.
    
9571.
        /**
9572.
         * Flag to indicate if DataTables is to use its smart filtering or not.
9573.
         *  @type boolean
9574.
         *  @default true
9575.
         */
9576.
        "bSmart": true
9577.
    };
9578.
    
9579.
    
9580.
    
9581.
    
9582.
    /**
9583.
     * Template object for the way in which DataTables holds information about
9584.
     * each individual row. This is the object format used for the settings
9585.
     * aoData array.
9586.
     *  @namespace
9587.
     */
9588.
    DataTable.models.oRow = {
9589.
        /**
9590.
         * TR element for the row
9591.
         *  @type node
9592.
         *  @default null
9593.
         */
9594.
        "nTr": null,
9595.
    
9596.
        /**
9597.
         * Array of TD elements for each row. This is null until the row has been
9598.
         * created.
9599.
         *  @type array nodes
9600.
         *  @default []
9601.
         */
9602.
        "anCells": null,
9603.
    
9604.
        /**
9605.
         * Data object from the original data source for the row. This is either
9606.
         * an array if using the traditional form of DataTables, or an object if
9607.
         * using mData options. The exact type will depend on the passed in
9608.
         * data from the data source, or will be an array if using DOM a data
9609.
         * source.
9610.
         *  @type array|object
9611.
         *  @default []
9612.
         */
9613.
        "_aData": [],
9614.
    
9615.
        /**
9616.
         * Sorting data cache - this array is ostensibly the same length as the
9617.
         * number of columns (although each index is generated only as it is
9618.
         * needed), and holds the data that is used for sorting each column in the
9619.
         * row. We do this cache generation at the start of the sort in order that
9620.
         * the formatting of the sort data need be done only once for each cell
9621.
         * per sort. This array should not be read from or written to by anything
9622.
         * other than the master sorting methods.
9623.
         *  @type array
9624.
         *  @default null
9625.
         *  @private
9626.
         */
9627.
        "_aSortData": null,
9628.
    
9629.
        /**
9630.
         * Per cell filtering data cache. As per the sort data cache, used to
9631.
         * increase the performance of the filtering in DataTables
9632.
         *  @type array
9633.
         *  @default null
9634.
         *  @private
9635.
         */
9636.
        "_aFilterData": null,
9637.
    
9638.
        /**
9639.
         * Filtering data cache. This is the same as the cell filtering cache, but
9640.
         * in this case a string rather than an array. This is easily computed with
9641.
         * a join on `_aFilterData`, but is provided as a cache so the join isn't
9642.
         * needed on every search (memory traded for performance)
9643.
         *  @type array
9644.
         *  @default null
9645.
         *  @private
9646.
         */
9647.
        "_sFilterRow": null,
9648.
    
9649.
        /**
9650.
         * Cache of the class name that DataTables has applied to the row, so we
9651.
         * can quickly look at this variable rather than needing to do a DOM check
9652.
         * on className for the nTr property.
9653.
         *  @type string
9654.
         *  @default <i>Empty string</i>
9655.
         *  @private
9656.
         */
9657.
        "_sRowStripe": "",
9658.
    
9659.
        /**
9660.
         * Denote if the original data source was from the DOM, or the data source
9661.
         * object. This is used for invalidating data, so DataTables can
9662.
         * automatically read data from the original source, unless uninstructed
9663.
         * otherwise.
9664.
         *  @type string
9665.
         *  @default null
9666.
         *  @private
9667.
         */
9668.
        "src": null,
9669.
    
9670.
        /**
9671.
         * Index in the aoData array. This saves an indexOf lookup when we have the
9672.
         * object, but want to know the index
9673.
         *  @type integer
9674.
         *  @default -1
9675.
         *  @private
9676.
         */
9677.
        "idx": -1
9678.
    };
9679.
    
9680.
    
9681.
    /**
9682.
     * Template object for the column information object in DataTables. This object
9683.
     * is held in the settings aoColumns array and contains all the information that
9684.
     * DataTables needs about each individual column.
9685.
     *
9686.
     * Note that this object is related to {@link DataTable.defaults.column}
9687.
     * but this one is the internal data store for DataTables's cache of columns.
9688.
     * It should NOT be manipulated outside of DataTables. Any configuration should
9689.
     * be done through the initialisation options.
9690.
     *  @namespace
9691.
     */
9692.
    DataTable.models.oColumn = {
9693.
        /**
9694.
         * Column index. This could be worked out on-the-fly with $.inArray, but it
9695.
         * is faster to just hold it as a variable
9696.
         *  @type integer
9697.
         *  @default null
9698.
         */
9699.
        "idx": null,
9700.
    
9701.
        /**
9702.
         * A list of the columns that sorting should occur on when this column
9703.
         * is sorted. That this property is an array allows multi-column sorting
9704.
         * to be defined for a column (for example first name / last name columns
9705.
         * would benefit from this). The values are integers pointing to the
9706.
         * columns to be sorted on (typically it will be a single integer pointing
9707.
         * at itself, but that doesn't need to be the case).
9708.
         *  @type array
9709.
         */
9710.
        "aDataSort": null,
9711.
    
9712.
        /**
9713.
         * Define the sorting directions that are applied to the column, in sequence
9714.
         * as the column is repeatedly sorted upon - i.e. the first value is used
9715.
         * as the sorting direction when the column if first sorted (clicked on).
9716.
         * Sort it again (click again) and it will move on to the next index.
9717.
         * Repeat until loop.
9718.
         *  @type array
9719.
         */
9720.
        "asSorting": null,
9721.
    
9722.
        /**
9723.
         * Flag to indicate if the column is searchable, and thus should be included
9724.
         * in the filtering or not.
9725.
         *  @type boolean
9726.
         */
9727.
        "bSearchable": null,
9728.
    
9729.
        /**
9730.
         * Flag to indicate if the column is sortable or not.
9731.
         *  @type boolean
9732.
         */
9733.
        "bSortable": null,
9734.
    
9735.
        /**
9736.
         * Flag to indicate if the column is currently visible in the table or not
9737.
         *  @type boolean
9738.
         */
9739.
        "bVisible": null,
9740.
    
9741.
        /**
9742.
         * Store for manual type assignment using the `column.type` option. This
9743.
         * is held in store so we can manipulate the column's `sType` property.
9744.
         *  @type string
9745.
         *  @default null
9746.
         *  @private
9747.
         */
9748.
        "_sManualType": null,
9749.
    
9750.
        /**
9751.
         * Flag to indicate if HTML5 data attributes should be used as the data
9752.
         * source for filtering or sorting. True is either are.
9753.
         *  @type boolean
9754.
         *  @default false
9755.
         *  @private
9756.
         */
9757.
        "_bAttrSrc": false,
9758.
    
9759.
        /**
9760.
         * Developer definable function that is called whenever a cell is created (Ajax source,
9761.
         * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9762.
         * allowing you to modify the DOM element (add background colour for example) when the
9763.
         * element is available.
9764.
         *  @type function
9765.
         *  @param {element} nTd The TD node that has been created
9766.
         *  @param {*} sData The Data for the cell
9767.
         *  @param {array|object} oData The data for the whole row
9768.
         *  @param {int} iRow The row index for the aoData data store
9769.
         *  @default null
9770.
         */
9771.
        "fnCreatedCell": null,
9772.
    
9773.
        /**
9774.
         * Function to get data from a cell in a column. You should <b>never</b>
9775.
         * access data directly through _aData internally in DataTables - always use
9776.
         * the method attached to this property. It allows mData to function as
9777.
         * required. This function is automatically assigned by the column
9778.
         * initialisation method
9779.
         *  @type function
9780.
         *  @param {array|object} oData The data array/object for the array
9781.
         *    (i.e. aoData[]._aData)
9782.
         *  @param {string} sSpecific The specific data type you want to get -
9783.
         *    'display', 'type' 'filter' 'sort'
9784.
         *  @returns {*} The data for the cell from the given row's data
9785.
         *  @default null
9786.
         */
9787.
        "fnGetData": null,
9788.
    
9789.
        /**
9790.
         * Function to set data for a cell in the column. You should <b>never</b>
9791.
         * set the data directly to _aData internally in DataTables - always use
9792.
         * this method. It allows mData to function as required. This function
9793.
         * is automatically assigned by the column initialisation method
9794.
         *  @type function
9795.
         *  @param {array|object} oData The data array/object for the array
9796.
         *    (i.e. aoData[]._aData)
9797.
         *  @param {*} sValue Value to set
9798.
         *  @default null
9799.
         */
9800.
        "fnSetData": null,
9801.
    
9802.
        /**
9803.
         * Property to read the value for the cells in the column from the data
9804.
         * source array / object. If null, then the default content is used, if a
9805.
         * function is given then the return from the function is used.
9806.
         *  @type function|int|string|null
9807.
         *  @default null
9808.
         */
9809.
        "mData": null,
9810.
    
9811.
        /**
9812.
         * Partner property to mData which is used (only when defined) to get
9813.
         * the data - i.e. it is basically the same as mData, but without the
9814.
         * 'set' option, and also the data fed to it is the result from mData.
9815.
         * This is the rendering method to match the data method of mData.
9816.
         *  @type function|int|string|null
9817.
         *  @default null
9818.
         */
9819.
        "mRender": null,
9820.
    
9821.
        /**
9822.
         * Unique header TH/TD element for this column - this is what the sorting
9823.
         * listener is attached to (if sorting is enabled.)
9824.
         *  @type node
9825.
         *  @default null
9826.
         */
9827.
        "nTh": null,
9828.
    
9829.
        /**
9830.
         * Unique footer TH/TD element for this column (if there is one). Not used
9831.
         * in DataTables as such, but can be used for plug-ins to reference the
9832.
         * footer for each column.
9833.
         *  @type node
9834.
         *  @default null
9835.
         */
9836.
        "nTf": null,
9837.
    
9838.
        /**
9839.
         * The class to apply to all TD elements in the table's TBODY for the column
9840.
         *  @type string
9841.
         *  @default null
9842.
         */
9843.
        "sClass": null,
9844.
    
9845.
        /**
9846.
         * When DataTables calculates the column widths to assign to each column,
9847.
         * it finds the longest string in each column and then constructs a
9848.
         * temporary table and reads the widths from that. The problem with this
9849.
         * is that "mmm" is much wider then "iiii", but the latter is a longer
9850.
         * string - thus the calculation can go wrong (doing it properly and putting
9851.
         * it into an DOM object and measuring that is horribly(!) slow). Thus as
9852.
         * a "work around" we provide this option. It will append its value to the
9853.
         * text that is found to be the longest string for the column - i.e. padding.
9854.
         *  @type string
9855.
         */
9856.
        "sContentPadding": null,
9857.
    
9858.
        /**
9859.
         * Allows a default value to be given for a column's data, and will be used
9860.
         * whenever a null data source is encountered (this can be because mData
9861.
         * is set to null, or because the data source itself is null).
9862.
         *  @type string
9863.
         *  @default null
9864.
         */
9865.
        "sDefaultContent": null,
9866.
    
9867.
        /**
9868.
         * Name for the column, allowing reference to the column by name as well as
9869.
         * by index (needs a lookup to work by name).
9870.
         *  @type string
9871.
         */
9872.
        "sName": null,
9873.
    
9874.
        /**
9875.
         * Custom sorting data type - defines which of the available plug-ins in
9876.
         * afnSortData the custom sorting will use - if any is defined.
9877.
         *  @type string
9878.
         *  @default std
9879.
         */
9880.
        "sSortDataType": 'std',
9881.
    
9882.
        /**
9883.
         * Class to be applied to the header element when sorting on this column
9884.
         *  @type string
9885.
         *  @default null
9886.
         */
9887.
        "sSortingClass": null,
9888.
    
9889.
        /**
9890.
         * Class to be applied to the header element when sorting on this column -
9891.
         * when jQuery UI theming is used.
9892.
         *  @type string
9893.
         *  @default null
9894.
         */
9895.
        "sSortingClassJUI": null,
9896.
    
9897.
        /**
9898.
         * Title of the column - what is seen in the TH element (nTh).
9899.
         *  @type string
9900.
         */
9901.
        "sTitle": null,
9902.
    
9903.
        /**
9904.
         * Column sorting and filtering type
9905.
         *  @type string
9906.
         *  @default null
9907.
         */
9908.
        "sType": null,
9909.
    
9910.
        /**
9911.
         * Width of the column
9912.
         *  @type string
9913.
         *  @default null
9914.
         */
9915.
        "sWidth": null,
9916.
    
9917.
        /**
9918.
         * Width of the column when it was first "encountered"
9919.
         *  @type string
9920.
         *  @default null
9921.
         */
9922.
        "sWidthOrig": null
9923.
    };
9924.
    
9925.
    
9926.
    /*
9927.
     * Developer note: The properties of the object below are given in Hungarian
9928.
     * notation, that was used as the interface for DataTables prior to v1.10, however
9929.
     * from v1.10 onwards the primary interface is camel case. In order to avoid
9930.
     * breaking backwards compatibility utterly with this change, the Hungarian
9931.
     * version is still, internally the primary interface, but is is not documented
9932.
     * - hence the @name tags in each doc comment. This allows a Javascript function
9933.
     * to create a map from Hungarian notation to camel case (going the other direction
9934.
     * would require each property to be listed, which would at around 3K to the size
9935.
     * of DataTables, while this method is about a 0.5K hit.
9936.
     *
9937.
     * Ultimately this does pave the way for Hungarian notation to be dropped
9938.
     * completely, but that is a massive amount of work and will break current
9939.
     * installs (therefore is on-hold until v2).
9940.
     */
9941.
    
9942.
    /**
9943.
     * Initialisation options that can be given to DataTables at initialisation
9944.
     * time.
9945.
     *  @namespace
9946.
     */
9947.
    DataTable.defaults = {
9948.
        /**
9949.
         * An array of data to use for the table, passed in at initialisation which
9950.
         * will be used in preference to any data which is already in the DOM. This is
9951.
         * particularly useful for constructing tables purely in Javascript, for
9952.
         * example with a custom Ajax call.
9953.
         *  @type array
9954.
         *  @default null
9955.
         *
9956.
         *  @dtopt Option
9957.
         *  @name DataTable.defaults.data
9958.
         *
9959.
         *  @example
9960.
         *    // Using a 2D array data source
9961.
         *    $(document).ready( function () {
9962.
         *      $('#example').dataTable( {
9963.
         *        "data": [
9964.
         *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9965.
         *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9966.
         *        ],
9967.
         *        "columns": [
9968.
         *          { "title": "Engine" },
9969.
         *          { "title": "Browser" },
9970.
         *          { "title": "Platform" },
9971.
         *          { "title": "Version" },
9972.
         *          { "title": "Grade" }
9973.
         *        ]
9974.
         *      } );
9975.
         *    } );
9976.
         *
9977.
         *  @example
9978.
         *    // Using an array of objects as a data source (`data`)
9979.
         *    $(document).ready( function () {
9980.
         *      $('#example').dataTable( {
9981.
         *        "data": [
9982.
         *          {
9983.
         *            "engine":   "Trident",
9984.
         *            "browser":  "Internet Explorer 4.0",
9985.
         *            "platform": "Win 95+",
9986.
         *            "version":  4,
9987.
         *            "grade":    "X"
9988.
         *          },
9989.
         *          {
9990.
         *            "engine":   "Trident",
9991.
         *            "browser":  "Internet Explorer 5.0",
9992.
         *            "platform": "Win 95+",
9993.
         *            "version":  5,
9994.
         *            "grade":    "C"
9995.
         *          }
9996.
         *        ],
9997.
         *        "columns": [
9998.
         *          { "title": "Engine",   "data": "engine" },
9999.
         *          { "title": "Browser",  "data": "browser" },
10000.
         *          { "title": "Platform", "data": "platform" },
10001.
         *          { "title": "Version",  "data": "version" },
10002.
         *          { "title": "Grade",    "data": "grade" }
10003.
         *        ]
10004.
         *      } );
10005.
         *    } );
10006.
         */
10007.
        "aaData": null,
10008.
    
10009.
    
10010.
        /**
10011.
         * If ordering is enabled, then DataTables will perform a first pass sort on
10012.
         * initialisation. You can define which column(s) the sort is performed
10013.
         * upon, and the sorting direction, with this variable. The `sorting` array
10014.
         * should contain an array for each column to be sorted initially containing
10015.
         * the column's index and a direction string ('asc' or 'desc').
10016.
         *  @type array
10017.
         *  @default [[0,'asc']]
10018.
         *
10019.
         *  @dtopt Option
10020.
         *  @name DataTable.defaults.order
10021.
         *
10022.
         *  @example
10023.
         *    // Sort by 3rd column first, and then 4th column
10024.
         *    $(document).ready( function() {
10025.
         *      $('#example').dataTable( {
10026.
         *        "order": [[2,'asc'], [3,'desc']]
10027.
         *      } );
10028.
         *    } );
10029.
         *
10030.
         *    // No initial sorting
10031.
         *    $(document).ready( function() {
10032.
         *      $('#example').dataTable( {
10033.
         *        "order": []
10034.
         *      } );
10035.
         *    } );
10036.
         */
10037.
        "aaSorting": [[0,'asc']],
10038.
    
10039.
    
10040.
        /**
10041.
         * This parameter is basically identical to the `sorting` parameter, but
10042.
         * cannot be overridden by user interaction with the table. What this means
10043.
         * is that you could have a column (visible or hidden) which the sorting
10044.
         * will always be forced on first - any sorting after that (from the user)
10045.
         * will then be performed as required. This can be useful for grouping rows
10046.
         * together.
10047.
         *  @type array
10048.
         *  @default null
10049.
         *
10050.
         *  @dtopt Option
10051.
         *  @name DataTable.defaults.orderFixed
10052.
         *
10053.
         *  @example
10054.
         *    $(document).ready( function() {
10055.
         *      $('#example').dataTable( {
10056.
         *        "orderFixed": [[0,'asc']]
10057.
         *      } );
10058.
         *    } )
10059.
         */
10060.
        "aaSortingFixed": [],
10061.
    
10062.
    
10063.
        /**
10064.
         * DataTables can be instructed to load data to display in the table from a
10065.
         * Ajax source. This option defines how that Ajax call is made and where to.
10066.
         *
10067.
         * The `ajax` property has three different modes of operation, depending on
10068.
         * how it is defined. These are:
10069.
         *
10070.
         * * `string` - Set the URL from where the data should be loaded from.
10071.
         * * `object` - Define properties for `jQuery.ajax`.
10072.
         * * `function` - Custom data get function
10073.
         *
10074.
         * `string`
10075.
         * --------
10076.
         *
10077.
         * As a string, the `ajax` property simply defines the URL from which
10078.
         * DataTables will load data.
10079.
         *
10080.
         * `object`
10081.
         * --------
10082.
         *
10083.
         * As an object, the parameters in the object are passed to
10084.
         * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
10085.
         * of the Ajax request. DataTables has a number of default parameters which
10086.
         * you can override using this option. Please refer to the jQuery
10087.
         * documentation for a full description of the options available, although
10088.
         * the following parameters provide additional options in DataTables or
10089.
         * require special consideration:
10090.
         *
10091.
         * * `data` - As with jQuery, `data` can be provided as an object, but it
10092.
         *   can also be used as a function to manipulate the data DataTables sends
10093.
         *   to the server. The function takes a single parameter, an object of
10094.
         *   parameters with the values that DataTables has readied for sending. An
10095.
         *   object may be returned which will be merged into the DataTables
10096.
         *   defaults, or you can add the items to the object that was passed in and
10097.
         *   not return anything from the function. This supersedes `fnServerParams`
10098.
         *   from DataTables 1.9-.
10099.
         *
10100.
         * * `dataSrc` - By default DataTables will look for the property `data` (or
10101.
         *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
10102.
         *   from an Ajax source or for server-side processing - this parameter
10103.
         *   allows that property to be changed. You can use Javascript dotted
10104.
         *   object notation to get a data source for multiple levels of nesting, or
10105.
         *   it my be used as a function. As a function it takes a single parameter,
10106.
         *   the JSON returned from the server, which can be manipulated as
10107.
         *   required, with the returned value being that used by DataTables as the
10108.
         *   data source for the table. This supersedes `sAjaxDataProp` from
10109.
         *   DataTables 1.9-.
10110.
         *
10111.
         * * `success` - Should not be overridden it is used internally in
10112.
         *   DataTables. To manipulate / transform the data returned by the server
10113.
         *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
10114.
         *
10115.
         * `function`
10116.
         * ----------
10117.
         *
10118.
         * As a function, making the Ajax call is left up to yourself allowing
10119.
         * complete control of the Ajax request. Indeed, if desired, a method other
10120.
         * than Ajax could be used to obtain the required data, such as Web storage
10121.
         * or an AIR database.
10122.
         *
10123.
         * The function is given four parameters and no return is required. The
10124.
         * parameters are:
10125.
         *
10126.
         * 1. _object_ - Data to send to the server
10127.
         * 2. _function_ - Callback function that must be executed when the required
10128.
         *    data has been obtained. That data should be passed into the callback
10129.
         *    as the only parameter
10130.
         * 3. _object_ - DataTables settings object for the table
10131.
         *
10132.
         * Note that this supersedes `fnServerData` from DataTables 1.9-.
10133.
         *
10134.
         *  @type string|object|function
10135.
         *  @default null
10136.
         *
10137.
         *  @dtopt Option
10138.
         *  @name DataTable.defaults.ajax
10139.
         *  @since 1.10.0
10140.
         *
10141.
         * @example
10142.
         *   // Get JSON data from a file via Ajax.
10143.
         *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
10144.
         *   $('#example').dataTable( {
10145.
         *     "ajax": "data.json"
10146.
         *   } );
10147.
         *
10148.
         * @example
10149.
         *   // Get JSON data from a file via Ajax, using `dataSrc` to change
10150.
         *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
10151.
         *   $('#example').dataTable( {
10152.
         *     "ajax": {
10153.
         *       "url": "data.json",
10154.
         *       "dataSrc": "tableData"
10155.
         *     }
10156.
         *   } );
10157.
         *
10158.
         * @example
10159.
         *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
10160.
         *   // from a plain array rather than an array in an object
10161.
         *   $('#example').dataTable( {
10162.
         *     "ajax": {
10163.
         *       "url": "data.json",
10164.
         *       "dataSrc": ""
10165.
         *     }
10166.
         *   } );
10167.
         *
10168.
         * @example
10169.
         *   // Manipulate the data returned from the server - add a link to data
10170.
         *   // (note this can, should, be done using `render` for the column - this
10171.
         *   // is just a simple example of how the data can be manipulated).
10172.
         *   $('#example').dataTable( {
10173.
         *     "ajax": {
10174.
         *       "url": "data.json",
10175.
         *       "dataSrc": function ( json ) {
10176.
         *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
10177.
         *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
10178.
         *         }
10179.
         *         return json;
10180.
         *       }
10181.
         *     }
10182.
         *   } );
10183.
         *
10184.
         * @example
10185.
         *   // Add data to the request
10186.
         *   $('#example').dataTable( {
10187.
         *     "ajax": {
10188.
         *       "url": "data.json",
10189.
         *       "data": function ( d ) {
10190.
         *         return {
10191.
         *           "extra_search": $('#extra').val()
10192.
         *         };
10193.
         *       }
10194.
         *     }
10195.
         *   } );
10196.
         *
10197.
         * @example
10198.
         *   // Send request as POST
10199.
         *   $('#example').dataTable( {
10200.
         *     "ajax": {
10201.
         *       "url": "data.json",
10202.
         *       "type": "POST"
10203.
         *     }
10204.
         *   } );
10205.
         *
10206.
         * @example
10207.
         *   // Get the data from localStorage (could interface with a form for
10208.
         *   // adding, editing and removing rows).
10209.
         *   $('#example').dataTable( {
10210.
         *     "ajax": function (data, callback, settings) {
10211.
         *       callback(
10212.
         *         JSON.parse( localStorage.getItem('dataTablesData') )
10213.
         *       );
10214.
         *     }
10215.
         *   } );
10216.
         */
10217.
        "ajax": null,
10218.
    
10219.
    
10220.
        /**
10221.
         * This parameter allows you to readily specify the entries in the length drop
10222.
         * down menu that DataTables shows when pagination is enabled. It can be
10223.
         * either a 1D array of options which will be used for both the displayed
10224.
         * option and the value, or a 2D array which will use the array in the first
10225.
         * position as the value, and the array in the second position as the
10226.
         * displayed options (useful for language strings such as 'All').
10227.
         *
10228.
         * Note that the `pageLength` property will be automatically set to the
10229.
         * first value given in this array, unless `pageLength` is also provided.
10230.
         *  @type array
10231.
         *  @default [ 10, 25, 50, 100 ]
10232.
         *
10233.
         *  @dtopt Option
10234.
         *  @name DataTable.defaults.lengthMenu
10235.
         *
10236.
         *  @example
10237.
         *    $(document).ready( function() {
10238.
         *      $('#example').dataTable( {
10239.
         *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
10240.
         *      } );
10241.
         *    } );
10242.
         */
10243.
        "aLengthMenu": [ 10, 25, 50, 100 ],
10244.
    
10245.
    
10246.
        /**
10247.
         * The `columns` option in the initialisation parameter allows you to define
10248.
         * details about the way individual columns behave. For a full list of
10249.
         * column options that can be set, please see
10250.
         * {@link DataTable.defaults.column}. Note that if you use `columns` to
10251.
         * define your columns, you must have an entry in the array for every single
10252.
         * column that you have in your table (these can be null if you don't which
10253.
         * to specify any options).
10254.
         *  @member
10255.
         *
10256.
         *  @name DataTable.defaults.column
10257.
         */
10258.
        "aoColumns": null,
10259.
    
10260.
        /**
10261.
         * Very similar to `columns`, `columnDefs` allows you to target a specific
10262.
         * column, multiple columns, or all columns, using the `targets` property of
10263.
         * each object in the array. This allows great flexibility when creating
10264.
         * tables, as the `columnDefs` arrays can be of any length, targeting the
10265.
         * columns you specifically want. `columnDefs` may use any of the column
10266.
         * options available: {@link DataTable.defaults.column}, but it _must_
10267.
         * have `targets` defined in each object in the array. Values in the `targets`
10268.
         * array may be:
10269.
         *   <ul>
10270.
         *     <li>a string - class name will be matched on the TH for the column</li>
10271.
         *     <li>0 or a positive integer - column index counting from the left</li>
10272.
         *     <li>a negative integer - column index counting from the right</li>
10273.
         *     <li>the string "_all" - all columns (i.e. assign a default)</li>
10274.
         *   </ul>
10275.
         *  @member
10276.
         *
10277.
         *  @name DataTable.defaults.columnDefs
10278.
         */
10279.
        "aoColumnDefs": null,
10280.
    
10281.
    
10282.
        /**
10283.
         * Basically the same as `search`, this parameter defines the individual column
10284.
         * filtering state at initialisation time. The array must be of the same size
10285.
         * as the number of columns, and each element be an object with the parameters
10286.
         * `search` and `escapeRegex` (the latter is optional). 'null' is also
10287.
         * accepted and the default will be used.
10288.
         *  @type array
10289.
         *  @default []
10290.
         *
10291.
         *  @dtopt Option
10292.
         *  @name DataTable.defaults.searchCols
10293.
         *
10294.
         *  @example
10295.
         *    $(document).ready( function() {
10296.
         *      $('#example').dataTable( {
10297.
         *        "searchCols": [
10298.
         *          null,
10299.
         *          { "search": "My filter" },
10300.
         *          null,
10301.
         *          { "search": "^[0-9]", "escapeRegex": false }
10302.
         *        ]
10303.
         *      } );
10304.
         *    } )
10305.
         */
10306.
        "aoSearchCols": [],
10307.
    
10308.
    
10309.
        /**
10310.
         * An array of CSS classes that should be applied to displayed rows. This
10311.
         * array may be of any length, and DataTables will apply each class
10312.
         * sequentially, looping when required.
10313.
         *  @type array
10314.
         *  @default null <i>Will take the values determined by the `oClasses.stripe*`
10315.
         *    options</i>
10316.
         *
10317.
         *  @dtopt Option
10318.
         *  @name DataTable.defaults.stripeClasses
10319.
         *
10320.
         *  @example
10321.
         *    $(document).ready( function() {
10322.
         *      $('#example').dataTable( {
10323.
         *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10324.
         *      } );
10325.
         *    } )
10326.
         */
10327.
        "asStripeClasses": null,
10328.
    
10329.
    
10330.
        /**
10331.
         * Enable or disable automatic column width calculation. This can be disabled
10332.
         * as an optimisation (it takes some time to calculate the widths) if the
10333.
         * tables widths are passed in using `columns`.
10334.
         *  @type boolean
10335.
         *  @default true
10336.
         *
10337.
         *  @dtopt Features
10338.
         *  @name DataTable.defaults.autoWidth
10339.
         *
10340.
         *  @example
10341.
         *    $(document).ready( function () {
10342.
         *      $('#example').dataTable( {
10343.
         *        "autoWidth": false
10344.
         *      } );
10345.
         *    } );
10346.
         */
10347.
        "bAutoWidth": true,
10348.
    
10349.
    
10350.
        /**
10351.
         * Deferred rendering can provide DataTables with a huge speed boost when you
10352.
         * are using an Ajax or JS data source for the table. This option, when set to
10353.
         * true, will cause DataTables to defer the creation of the table elements for
10354.
         * each row until they are needed for a draw - saving a significant amount of
10355.
         * time.
10356.
         *  @type boolean
10357.
         *  @default false
10358.
         *
10359.
         *  @dtopt Features
10360.
         *  @name DataTable.defaults.deferRender
10361.
         *
10362.
         *  @example
10363.
         *    $(document).ready( function() {
10364.
         *      $('#example').dataTable( {
10365.
         *        "ajax": "sources/arrays.txt",
10366.
         *        "deferRender": true
10367.
         *      } );
10368.
         *    } );
10369.
         */
10370.
        "bDeferRender": false,
10371.
    
10372.
    
10373.
        /**
10374.
         * Replace a DataTable which matches the given selector and replace it with
10375.
         * one which has the properties of the new initialisation object passed. If no
10376.
         * table matches the selector, then the new DataTable will be constructed as
10377.
         * per normal.
10378.
         *  @type boolean
10379.
         *  @default false
10380.
         *
10381.
         *  @dtopt Options
10382.
         *  @name DataTable.defaults.destroy
10383.
         *
10384.
         *  @example
10385.
         *    $(document).ready( function() {
10386.
         *      $('#example').dataTable( {
10387.
         *        "srollY": "200px",
10388.
         *        "paginate": false
10389.
         *      } );
10390.
         *
10391.
         *      // Some time later....
10392.
         *      $('#example').dataTable( {
10393.
         *        "filter": false,
10394.
         *        "destroy": true
10395.
         *      } );
10396.
         *    } );
10397.
         */
10398.
        "bDestroy": false,
10399.
    
10400.
    
10401.
        /**
10402.
         * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10403.
         * that it allows the end user to input multiple words (space separated) and
10404.
         * will match a row containing those words, even if not in the order that was
10405.
         * specified (this allow matching across multiple columns). Note that if you
10406.
         * wish to use filtering in DataTables this must remain 'true' - to remove the
10407.
         * default filtering input box and retain filtering abilities, please use
10408.
         * {@link DataTable.defaults.dom}.
10409.
         *  @type boolean
10410.
         *  @default true
10411.
         *
10412.
         *  @dtopt Features
10413.
         *  @name DataTable.defaults.searching
10414.
         *
10415.
         *  @example
10416.
         *    $(document).ready( function () {
10417.
         *      $('#example').dataTable( {
10418.
         *        "searching": false
10419.
         *      } );
10420.
         *    } );
10421.
         */
10422.
        "bFilter": true,
10423.
    
10424.
    
10425.
        /**
10426.
         * Enable or disable the table information display. This shows information
10427.
         * about the data that is currently visible on the page, including information
10428.
         * about filtered data if that action is being performed.
10429.
         *  @type boolean
10430.
         *  @default true
10431.
         *
10432.
         *  @dtopt Features
10433.
         *  @name DataTable.defaults.info
10434.
         *
10435.
         *  @example
10436.
         *    $(document).ready( function () {
10437.
         *      $('#example').dataTable( {
10438.
         *        "info": false
10439.
         *      } );
10440.
         *    } );
10441.
         */
10442.
        "bInfo": true,
10443.
    
10444.
    
10445.
        /**
10446.
         * Allows the end user to select the size of a formatted page from a select
10447.
         * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10448.
         *  @type boolean
10449.
         *  @default true
10450.
         *
10451.
         *  @dtopt Features
10452.
         *  @name DataTable.defaults.lengthChange
10453.
         *
10454.
         *  @example
10455.
         *    $(document).ready( function () {
10456.
         *      $('#example').dataTable( {
10457.
         *        "lengthChange": false
10458.
         *      } );
10459.
         *    } );
10460.
         */
10461.
        "bLengthChange": true,
10462.
    
10463.
    
10464.
        /**
10465.
         * Enable or disable pagination.
10466.
         *  @type boolean
10467.
         *  @default true
10468.
         *
10469.
         *  @dtopt Features
10470.
         *  @name DataTable.defaults.paging
10471.
         *
10472.
         *  @example
10473.
         *    $(document).ready( function () {
10474.
         *      $('#example').dataTable( {
10475.
         *        "paging": false
10476.
         *      } );
10477.
         *    } );
10478.
         */
10479.
        "bPaginate": true,
10480.
    
10481.
    
10482.
        /**
10483.
         * Enable or disable the display of a 'processing' indicator when the table is
10484.
         * being processed (e.g. a sort). This is particularly useful for tables with
10485.
         * large amounts of data where it can take a noticeable amount of time to sort
10486.
         * the entries.
10487.
         *  @type boolean
10488.
         *  @default false
10489.
         *
10490.
         *  @dtopt Features
10491.
         *  @name DataTable.defaults.processing
10492.
         *
10493.
         *  @example
10494.
         *    $(document).ready( function () {
10495.
         *      $('#example').dataTable( {
10496.
         *        "processing": true
10497.
         *      } );
10498.
         *    } );
10499.
         */
10500.
        "bProcessing": false,
10501.
    
10502.
    
10503.
        /**
10504.
         * Retrieve the DataTables object for the given selector. Note that if the
10505.
         * table has already been initialised, this parameter will cause DataTables
10506.
         * to simply return the object that has already been set up - it will not take
10507.
         * account of any changes you might have made to the initialisation object
10508.
         * passed to DataTables (setting this parameter to true is an acknowledgement
10509.
         * that you understand this). `destroy` can be used to reinitialise a table if
10510.
         * you need.
10511.
         *  @type boolean
10512.
         *  @default false
10513.
         *
10514.
         *  @dtopt Options
10515.
         *  @name DataTable.defaults.retrieve
10516.
         *
10517.
         *  @example
10518.
         *    $(document).ready( function() {
10519.
         *      initTable();
10520.
         *      tableActions();
10521.
         *    } );
10522.
         *
10523.
         *    function initTable ()
10524.
         *    {
10525.
         *      return $('#example').dataTable( {
10526.
         *        "scrollY": "200px",
10527.
         *        "paginate": false,
10528.
         *        "retrieve": true
10529.
         *      } );
10530.
         *    }
10531.
         *
10532.
         *    function tableActions ()
10533.
         *    {
10534.
         *      var table = initTable();
10535.
         *      // perform API operations with oTable
10536.
         *    }
10537.
         */
10538.
        "bRetrieve": false,
10539.
    
10540.
    
10541.
        /**
10542.
         * When vertical (y) scrolling is enabled, DataTables will force the height of
10543.
         * the table's viewport to the given height at all times (useful for layout).
10544.
         * However, this can look odd when filtering data down to a small data set,
10545.
         * and the footer is left "floating" further down. This parameter (when
10546.
         * enabled) will cause DataTables to collapse the table's viewport down when
10547.
         * the result set will fit within the given Y height.
10548.
         *  @type boolean
10549.
         *  @default false
10550.
         *
10551.
         *  @dtopt Options
10552.
         *  @name DataTable.defaults.scrollCollapse
10553.
         *
10554.
         *  @example
10555.
         *    $(document).ready( function() {
10556.
         *      $('#example').dataTable( {
10557.
         *        "scrollY": "200",
10558.
         *        "scrollCollapse": true
10559.
         *      } );
10560.
         *    } );
10561.
         */
10562.
        "bScrollCollapse": false,
10563.
    
10564.
    
10565.
        /**
10566.
         * Configure DataTables to use server-side processing. Note that the
10567.
         * `ajax` parameter must also be given in order to give DataTables a
10568.
         * source to obtain the required data for each draw.
10569.
         *  @type boolean
10570.
         *  @default false
10571.
         *
10572.
         *  @dtopt Features
10573.
         *  @dtopt Server-side
10574.
         *  @name DataTable.defaults.serverSide
10575.
         *
10576.
         *  @example
10577.
         *    $(document).ready( function () {
10578.
         *      $('#example').dataTable( {
10579.
         *        "serverSide": true,
10580.
         *        "ajax": "xhr.php"
10581.
         *      } );
10582.
         *    } );
10583.
         */
10584.
        "bServerSide": false,
10585.
    
10586.
    
10587.
        /**
10588.
         * Enable or disable sorting of columns. Sorting of individual columns can be
10589.
         * disabled by the `sortable` option for each column.
10590.
         *  @type boolean
10591.
         *  @default true
10592.
         *
10593.
         *  @dtopt Features
10594.
         *  @name DataTable.defaults.ordering
10595.
         *
10596.
         *  @example
10597.
         *    $(document).ready( function () {
10598.
         *      $('#example').dataTable( {
10599.
         *        "ordering": false
10600.
         *      } );
10601.
         *    } );
10602.
         */
10603.
        "bSort": true,
10604.
    
10605.
    
10606.
        /**
10607.
         * Enable or display DataTables' ability to sort multiple columns at the
10608.
         * same time (activated by shift-click by the user).
10609.
         *  @type boolean
10610.
         *  @default true
10611.
         *
10612.
         *  @dtopt Options
10613.
         *  @name DataTable.defaults.orderMulti
10614.
         *
10615.
         *  @example
10616.
         *    // Disable multiple column sorting ability
10617.
         *    $(document).ready( function () {
10618.
         *      $('#example').dataTable( {
10619.
         *        "orderMulti": false
10620.
         *      } );
10621.
         *    } );
10622.
         */
10623.
        "bSortMulti": true,
10624.
    
10625.
    
10626.
        /**
10627.
         * Allows control over whether DataTables should use the top (true) unique
10628.
         * cell that is found for a single column, or the bottom (false - default).
10629.
         * This is useful when using complex headers.
10630.
         *  @type boolean
10631.
         *  @default false
10632.
         *
10633.
         *  @dtopt Options
10634.
         *  @name DataTable.defaults.orderCellsTop
10635.
         *
10636.
         *  @example
10637.
         *    $(document).ready( function() {
10638.
         *      $('#example').dataTable( {
10639.
         *        "orderCellsTop": true
10640.
         *      } );
10641.
         *    } );
10642.
         */
10643.
        "bSortCellsTop": false,
10644.
    
10645.
    
10646.
        /**
10647.
         * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10648.
         * `sorting\_3` to the columns which are currently being sorted on. This is
10649.
         * presented as a feature switch as it can increase processing time (while
10650.
         * classes are removed and added) so for large data sets you might want to
10651.
         * turn this off.
10652.
         *  @type boolean
10653.
         *  @default true
10654.
         *
10655.
         *  @dtopt Features
10656.
         *  @name DataTable.defaults.orderClasses
10657.
         *
10658.
         *  @example
10659.
         *    $(document).ready( function () {
10660.
         *      $('#example').dataTable( {
10661.
         *        "orderClasses": false
10662.
         *      } );
10663.
         *    } );
10664.
         */
10665.
        "bSortClasses": true,
10666.
    
10667.
    
10668.
        /**
10669.
         * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10670.
         * used to save table display information such as pagination information,
10671.
         * display length, filtering and sorting. As such when the end user reloads
10672.
         * the page the display display will match what thy had previously set up.
10673.
         *
10674.
         * Due to the use of `localStorage` the default state saving is not supported
10675.
         * in IE6 or 7. If state saving is required in those browsers, use
10676.
         * `stateSaveCallback` to provide a storage solution such as cookies.
10677.
         *  @type boolean
10678.
         *  @default false
10679.
         *
10680.
         *  @dtopt Features
10681.
         *  @name DataTable.defaults.stateSave
10682.
         *
10683.
         *  @example
10684.
         *    $(document).ready( function () {
10685.
         *      $('#example').dataTable( {
10686.
         *        "stateSave": true
10687.
         *      } );
10688.
         *    } );
10689.
         */
10690.
        "bStateSave": false,
10691.
    
10692.
    
10693.
        /**
10694.
         * This function is called when a TR element is created (and all TD child
10695.
         * elements have been inserted), or registered if using a DOM source, allowing
10696.
         * manipulation of the TR element (adding classes etc).
10697.
         *  @type function
10698.
         *  @param {node} row "TR" element for the current row
10699.
         *  @param {array} data Raw data array for this row
10700.
         *  @param {int} dataIndex The index of this row in the internal aoData array
10701.
         *
10702.
         *  @dtopt Callbacks
10703.
         *  @name DataTable.defaults.createdRow
10704.
         *
10705.
         *  @example
10706.
         *    $(document).ready( function() {
10707.
         *      $('#example').dataTable( {
10708.
         *        "createdRow": function( row, data, dataIndex ) {
10709.
         *          // Bold the grade for all 'A' grade browsers
10710.
         *          if ( data[4] == "A" )
10711.
         *          {
10712.
         *            $('td:eq(4)', row).html( '<b>A</b>' );
10713.
         *          }
10714.
         *        }
10715.
         *      } );
10716.
         *    } );
10717.
         */
10718.
        "fnCreatedRow": null,
10719.
    
10720.
    
10721.
        /**
10722.
         * This function is called on every 'draw' event, and allows you to
10723.
         * dynamically modify any aspect you want about the created DOM.
10724.
         *  @type function
10725.
         *  @param {object} settings DataTables settings object
10726.
         *
10727.
         *  @dtopt Callbacks
10728.
         *  @name DataTable.defaults.drawCallback
10729.
         *
10730.
         *  @example
10731.
         *    $(document).ready( function() {
10732.
         *      $('#example').dataTable( {
10733.
         *        "drawCallback": function( settings ) {
10734.
         *          alert( 'DataTables has redrawn the table' );
10735.
         *        }
10736.
         *      } );
10737.
         *    } );
10738.
         */
10739.
        "fnDrawCallback": null,
10740.
    
10741.
    
10742.
        /**
10743.
         * Identical to fnHeaderCallback() but for the table footer this function
10744.
         * allows you to modify the table footer on every 'draw' event.
10745.
         *  @type function
10746.
         *  @param {node} foot "TR" element for the footer
10747.
         *  @param {array} data Full table data (as derived from the original HTML)
10748.
         *  @param {int} start Index for the current display starting point in the
10749.
         *    display array
10750.
         *  @param {int} end Index for the current display ending point in the
10751.
         *    display array
10752.
         *  @param {array int} display Index array to translate the visual position
10753.
         *    to the full data array
10754.
         *
10755.
         *  @dtopt Callbacks
10756.
         *  @name DataTable.defaults.footerCallback
10757.
         *
10758.
         *  @example
10759.
         *    $(document).ready( function() {
10760.
         *      $('#example').dataTable( {
10761.
         *        "footerCallback": function( tfoot, data, start, end, display ) {
10762.
         *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10763.
         *        }
10764.
         *      } );
10765.
         *    } )
10766.
         */
10767.
        "fnFooterCallback": null,
10768.
    
10769.
    
10770.
        /**
10771.
         * When rendering large numbers in the information element for the table
10772.
         * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10773.
         * to have a comma separator for the 'thousands' units (e.g. 1 million is
10774.
         * rendered as "1,000,000") to help readability for the end user. This
10775.
         * function will override the default method DataTables uses.
10776.
         *  @type function
10777.
         *  @member
10778.
         *  @param {int} toFormat number to be formatted
10779.
         *  @returns {string} formatted string for DataTables to show the number
10780.
         *
10781.
         *  @dtopt Callbacks
10782.
         *  @name DataTable.defaults.formatNumber
10783.
         *
10784.
         *  @example
10785.
         *    // Format a number using a single quote for the separator (note that
10786.
         *    // this can also be done with the language.thousands option)
10787.
         *    $(document).ready( function() {
10788.
         *      $('#example').dataTable( {
10789.
         *        "formatNumber": function ( toFormat ) {
10790.
         *          return toFormat.toString().replace(
10791.
         *            /\B(?=(\d{3})+(?!\d))/g, "'"
10792.
         *          );
10793.
         *        };
10794.
         *      } );
10795.
         *    } );
10796.
         */
10797.
        "fnFormatNumber": function ( toFormat ) {
10798.
            return toFormat.toString().replace(
10799.
                /\B(?=(\d{3})+(?!\d))/g,
10800.
                this.oLanguage.sThousands
10801.
            );
10802.
        },
10803.
    
10804.
    
10805.
        /**
10806.
         * This function is called on every 'draw' event, and allows you to
10807.
         * dynamically modify the header row. This can be used to calculate and
10808.
         * display useful information about the table.
10809.
         *  @type function
10810.
         *  @param {node} head "TR" element for the header
10811.
         *  @param {array} data Full table data (as derived from the original HTML)
10812.
         *  @param {int} start Index for the current display starting point in the
10813.
         *    display array
10814.
         *  @param {int} end Index for the current display ending point in the
10815.
         *    display array
10816.
         *  @param {array int} display Index array to translate the visual position
10817.
         *    to the full data array
10818.
         *
10819.
         *  @dtopt Callbacks
10820.
         *  @name DataTable.defaults.headerCallback
10821.
         *
10822.
         *  @example
10823.
         *    $(document).ready( function() {
10824.
         *      $('#example').dataTable( {
10825.
         *        "fheaderCallback": function( head, data, start, end, display ) {
10826.
         *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10827.
         *        }
10828.
         *      } );
10829.
         *    } )
10830.
         */
10831.
        "fnHeaderCallback": null,
10832.
    
10833.
    
10834.
        /**
10835.
         * The information element can be used to convey information about the current
10836.
         * state of the table. Although the internationalisation options presented by
10837.
         * DataTables are quite capable of dealing with most customisations, there may
10838.
         * be times where you wish to customise the string further. This callback
10839.
         * allows you to do exactly that.
10840.
         *  @type function
10841.
         *  @param {object} oSettings DataTables settings object
10842.
         *  @param {int} start Starting position in data for the draw
10843.
         *  @param {int} end End position in data for the draw
10844.
         *  @param {int} max Total number of rows in the table (regardless of
10845.
         *    filtering)
10846.
         *  @param {int} total Total number of rows in the data set, after filtering
10847.
         *  @param {string} pre The string that DataTables has formatted using it's
10848.
         *    own rules
10849.
         *  @returns {string} The string to be displayed in the information element.
10850.
         *
10851.
         *  @dtopt Callbacks
10852.
         *  @name DataTable.defaults.infoCallback
10853.
         *
10854.
         *  @example
10855.
         *    $('#example').dataTable( {
10856.
         *      "infoCallback": function( settings, start, end, max, total, pre ) {
10857.
         *        return start +" to "+ end;
10858.
         *      }
10859.
         *    } );
10860.
         */
10861.
        "fnInfoCallback": null,
10862.
    
10863.
    
10864.
        /**
10865.
         * Called when the table has been initialised. Normally DataTables will
10866.
         * initialise sequentially and there will be no need for this function,
10867.
         * however, this does not hold true when using external language information
10868.
         * since that is obtained using an async XHR call.
10869.
         *  @type function
10870.
         *  @param {object} settings DataTables settings object
10871.
         *  @param {object} json The JSON object request from the server - only
10872.
         *    present if client-side Ajax sourced data is used
10873.
         *
10874.
         *  @dtopt Callbacks
10875.
         *  @name DataTable.defaults.initComplete
10876.
         *
10877.
         *  @example
10878.
         *    $(document).ready( function() {
10879.
         *      $('#example').dataTable( {
10880.
         *        "initComplete": function(settings, json) {
10881.
         *          alert( 'DataTables has finished its initialisation.' );
10882.
         *        }
10883.
         *      } );
10884.
         *    } )
10885.
         */
10886.
        "fnInitComplete": null,
10887.
    
10888.
    
10889.
        /**
10890.
         * Called at the very start of each table draw and can be used to cancel the
10891.
         * draw by returning false, any other return (including undefined) results in
10892.
         * the full draw occurring).
10893.
         *  @type function
10894.
         *  @param {object} settings DataTables settings object
10895.
         *  @returns {boolean} False will cancel the draw, anything else (including no
10896.
         *    return) will allow it to complete.
10897.
         *
10898.
         *  @dtopt Callbacks
10899.
         *  @name DataTable.defaults.preDrawCallback
10900.
         *
10901.
         *  @example
10902.
         *    $(document).ready( function() {
10903.
         *      $('#example').dataTable( {
10904.
         *        "preDrawCallback": function( settings ) {
10905.
         *          if ( $('#test').val() == 1 ) {
10906.
         *            return false;
10907.
         *          }
10908.
         *        }
10909.
         *      } );
10910.
         *    } );
10911.
         */
10912.
        "fnPreDrawCallback": null,
10913.
    
10914.
    
10915.
        /**
10916.
         * This function allows you to 'post process' each row after it have been
10917.
         * generated for each table draw, but before it is rendered on screen. This
10918.
         * function might be used for setting the row class name etc.
10919.
         *  @type function
10920.
         *  @param {node} row "TR" element for the current row
10921.
         *  @param {array} data Raw data array for this row
10922.
         *  @param {int} displayIndex The display index for the current table draw
10923.
         *  @param {int} displayIndexFull The index of the data in the full list of
10924.
         *    rows (after filtering)
10925.
         *
10926.
         *  @dtopt Callbacks
10927.
         *  @name DataTable.defaults.rowCallback
10928.
         *
10929.
         *  @example
10930.
         *    $(document).ready( function() {
10931.
         *      $('#example').dataTable( {
10932.
         *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10933.
         *          // Bold the grade for all 'A' grade browsers
10934.
         *          if ( data[4] == "A" ) {
10935.
         *            $('td:eq(4)', row).html( '<b>A</b>' );
10936.
         *          }
10937.
         *        }
10938.
         *      } );
10939.
         *    } );
10940.
         */
10941.
        "fnRowCallback": null,
10942.
    
10943.
    
10944.
        /**
10945.
         * __Deprecated__ The functionality provided by this parameter has now been
10946.
         * superseded by that provided through `ajax`, which should be used instead.
10947.
         *
10948.
         * This parameter allows you to override the default function which obtains
10949.
         * the data from the server so something more suitable for your application.
10950.
         * For example you could use POST data, or pull information from a Gears or
10951.
         * AIR database.
10952.
         *  @type function
10953.
         *  @member
10954.
         *  @param {string} source HTTP source to obtain the data from (`ajax`)
10955.
         *  @param {array} data A key/value pair object containing the data to send
10956.
         *    to the server
10957.
         *  @param {function} callback to be called on completion of the data get
10958.
         *    process that will draw the data on the page.
10959.
         *  @param {object} settings DataTables settings object
10960.
         *
10961.
         *  @dtopt Callbacks
10962.
         *  @dtopt Server-side
10963.
         *  @name DataTable.defaults.serverData
10964.
         *
10965.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
10966.
         */
10967.
        "fnServerData": null,
10968.
    
10969.
    
10970.
        /**
10971.
         * __Deprecated__ The functionality provided by this parameter has now been
10972.
         * superseded by that provided through `ajax`, which should be used instead.
10973.
         *
10974.
         *  It is often useful to send extra data to the server when making an Ajax
10975.
         * request - for example custom filtering information, and this callback
10976.
         * function makes it trivial to send extra information to the server. The
10977.
         * passed in parameter is the data set that has been constructed by
10978.
         * DataTables, and you can add to this or modify it as you require.
10979.
         *  @type function
10980.
         *  @param {array} data Data array (array of objects which are name/value
10981.
         *    pairs) that has been constructed by DataTables and will be sent to the
10982.
         *    server. In the case of Ajax sourced data with server-side processing
10983.
         *    this will be an empty array, for server-side processing there will be a
10984.
         *    significant number of parameters!
10985.
         *  @returns {undefined} Ensure that you modify the data array passed in,
10986.
         *    as this is passed by reference.
10987.
         *
10988.
         *  @dtopt Callbacks
10989.
         *  @dtopt Server-side
10990.
         *  @name DataTable.defaults.serverParams
10991.
         *
10992.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
10993.
         */
10994.
        "fnServerParams": null,
10995.
    
10996.
    
10997.
        /**
10998.
         * Load the table state. With this function you can define from where, and how, the
10999.
         * state of a table is loaded. By default DataTables will load from `localStorage`
11000.
         * but you might wish to use a server-side database or cookies.
11001.
         *  @type function
11002.
         *  @member
11003.
         *  @param {object} settings DataTables settings object
11004.
         *  @param {object} callback Callback that can be executed when done. It
11005.
         *    should be passed the loaded state object.
11006.
         *  @return {object} The DataTables state object to be loaded
11007.
         *
11008.
         *  @dtopt Callbacks
11009.
         *  @name DataTable.defaults.stateLoadCallback
11010.
         *
11011.
         *  @example
11012.
         *    $(document).ready( function() {
11013.
         *      $('#example').dataTable( {
11014.
         *        "stateSave": true,
11015.
         *        "stateLoadCallback": function (settings, callback) {
11016.
         *          $.ajax( {
11017.
         *            "url": "/state_load",
11018.
         *            "dataType": "json",
11019.
         *            "success": function (json) {
11020.
         *              callback( json );
11021.
         *            }
11022.
         *          } );
11023.
         *        }
11024.
         *      } );
11025.
         *    } );
11026.
         */
11027.
        "fnStateLoadCallback": function ( settings ) {
11028.
            try {
11029.
                return JSON.parse(
11030.
                    (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
11031.
                        'DataTables_'+settings.sInstance+'_'+location.pathname
11032.
                    )
11033.
                );
11034.
            } catch (e) {
11035.
                return {};
11036.
            }
11037.
        },
11038.
    
11039.
    
11040.
        /**
11041.
         * Callback which allows modification of the saved state prior to loading that state.
11042.
         * This callback is called when the table is loading state from the stored data, but
11043.
         * prior to the settings object being modified by the saved state. Note that for
11044.
         * plug-in authors, you should use the `stateLoadParams` event to load parameters for
11045.
         * a plug-in.
11046.
         *  @type function
11047.
         *  @param {object} settings DataTables settings object
11048.
         *  @param {object} data The state object that is to be loaded
11049.
         *
11050.
         *  @dtopt Callbacks
11051.
         *  @name DataTable.defaults.stateLoadParams
11052.
         *
11053.
         *  @example
11054.
         *    // Remove a saved filter, so filtering is never loaded
11055.
         *    $(document).ready( function() {
11056.
         *      $('#example').dataTable( {
11057.
         *        "stateSave": true,
11058.
         *        "stateLoadParams": function (settings, data) {
11059.
         *          data.oSearch.sSearch = "";
11060.
         *        }
11061.
         *      } );
11062.
         *    } );
11063.
         *
11064.
         *  @example
11065.
         *    // Disallow state loading by returning false
11066.
         *    $(document).ready( function() {
11067.
         *      $('#example').dataTable( {
11068.
         *        "stateSave": true,
11069.
         *        "stateLoadParams": function (settings, data) {
11070.
         *          return false;
11071.
         *        }
11072.
         *      } );
11073.
         *    } );
11074.
         */
11075.
        "fnStateLoadParams": null,
11076.
    
11077.
    
11078.
        /**
11079.
         * Callback that is called when the state has been loaded from the state saving method
11080.
         * and the DataTables settings object has been modified as a result of the loaded state.
11081.
         *  @type function
11082.
         *  @param {object} settings DataTables settings object
11083.
         *  @param {object} data The state object that was loaded
11084.
         *
11085.
         *  @dtopt Callbacks
11086.
         *  @name DataTable.defaults.stateLoaded
11087.
         *
11088.
         *  @example
11089.
         *    // Show an alert with the filtering value that was saved
11090.
         *    $(document).ready( function() {
11091.
         *      $('#example').dataTable( {
11092.
         *        "stateSave": true,
11093.
         *        "stateLoaded": function (settings, data) {
11094.
         *          alert( 'Saved filter was: '+data.oSearch.sSearch );
11095.
         *        }
11096.
         *      } );
11097.
         *    } );
11098.
         */
11099.
        "fnStateLoaded": null,
11100.
    
11101.
    
11102.
        /**
11103.
         * Save the table state. This function allows you to define where and how the state
11104.
         * information for the table is stored By default DataTables will use `localStorage`
11105.
         * but you might wish to use a server-side database or cookies.
11106.
         *  @type function
11107.
         *  @member
11108.
         *  @param {object} settings DataTables settings object
11109.
         *  @param {object} data The state object to be saved
11110.
         *
11111.
         *  @dtopt Callbacks
11112.
         *  @name DataTable.defaults.stateSaveCallback
11113.
         *
11114.
         *  @example
11115.
         *    $(document).ready( function() {
11116.
         *      $('#example').dataTable( {
11117.
         *        "stateSave": true,
11118.
         *        "stateSaveCallback": function (settings, data) {
11119.
         *          // Send an Ajax request to the server with the state object
11120.
         *          $.ajax( {
11121.
         *            "url": "/state_save",
11122.
         *            "data": data,
11123.
         *            "dataType": "json",
11124.
         *            "method": "POST"
11125.
         *            "success": function () {}
11126.
         *          } );
11127.
         *        }
11128.
         *      } );
11129.
         *    } );
11130.
         */
11131.
        "fnStateSaveCallback": function ( settings, data ) {
11132.
            try {
11133.
                (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
11134.
                    'DataTables_'+settings.sInstance+'_'+location.pathname,
11135.
                    JSON.stringify( data )
11136.
                );
11137.
            } catch (e) {}
11138.
        },
11139.
    
11140.
    
11141.
        /**
11142.
         * Callback which allows modification of the state to be saved. Called when the table
11143.
         * has changed state a new state save is required. This method allows modification of
11144.
         * the state saving object prior to actually doing the save, including addition or
11145.
         * other state properties or modification. Note that for plug-in authors, you should
11146.
         * use the `stateSaveParams` event to save parameters for a plug-in.
11147.
         *  @type function
11148.
         *  @param {object} settings DataTables settings object
11149.
         *  @param {object} data The state object to be saved
11150.
         *
11151.
         *  @dtopt Callbacks
11152.
         *  @name DataTable.defaults.stateSaveParams
11153.
         *
11154.
         *  @example
11155.
         *    // Remove a saved filter, so filtering is never saved
11156.
         *    $(document).ready( function() {
11157.
         *      $('#example').dataTable( {
11158.
         *        "stateSave": true,
11159.
         *        "stateSaveParams": function (settings, data) {
11160.
         *          data.oSearch.sSearch = "";
11161.
         *        }
11162.
         *      } );
11163.
         *    } );
11164.
         */
11165.
        "fnStateSaveParams": null,
11166.
    
11167.
    
11168.
        /**
11169.
         * Duration for which the saved state information is considered valid. After this period
11170.
         * has elapsed the state will be returned to the default.
11171.
         * Value is given in seconds.
11172.
         *  @type int
11173.
         *  @default 7200 <i>(2 hours)</i>
11174.
         *
11175.
         *  @dtopt Options
11176.
         *  @name DataTable.defaults.stateDuration
11177.
         *
11178.
         *  @example
11179.
         *    $(document).ready( function() {
11180.
         *      $('#example').dataTable( {
11181.
         *        "stateDuration": 60*60*24; // 1 day
11182.
         *      } );
11183.
         *    } )
11184.
         */
11185.
        "iStateDuration": 7200,
11186.
    
11187.
    
11188.
        /**
11189.
         * When enabled DataTables will not make a request to the server for the first
11190.
         * page draw - rather it will use the data already on the page (no sorting etc
11191.
         * will be applied to it), thus saving on an XHR at load time. `deferLoading`
11192.
         * is used to indicate that deferred loading is required, but it is also used
11193.
         * to tell DataTables how many records there are in the full table (allowing
11194.
         * the information element and pagination to be displayed correctly). In the case
11195.
         * where a filtering is applied to the table on initial load, this can be
11196.
         * indicated by giving the parameter as an array, where the first element is
11197.
         * the number of records available after filtering and the second element is the
11198.
         * number of records without filtering (allowing the table information element
11199.
         * to be shown correctly).
11200.
         *  @type int | array
11201.
         *  @default null
11202.
         *
11203.
         *  @dtopt Options
11204.
         *  @name DataTable.defaults.deferLoading
11205.
         *
11206.
         *  @example
11207.
         *    // 57 records available in the table, no filtering applied
11208.
         *    $(document).ready( function() {
11209.
         *      $('#example').dataTable( {
11210.
         *        "serverSide": true,
11211.
         *        "ajax": "scripts/server_processing.php",
11212.
         *        "deferLoading": 57
11213.
         *      } );
11214.
         *    } );
11215.
         *
11216.
         *  @example
11217.
         *    // 57 records after filtering, 100 without filtering (an initial filter applied)
11218.
         *    $(document).ready( function() {
11219.
         *      $('#example').dataTable( {
11220.
         *        "serverSide": true,
11221.
         *        "ajax": "scripts/server_processing.php",
11222.
         *        "deferLoading": [ 57, 100 ],
11223.
         *        "search": {
11224.
         *          "search": "my_filter"
11225.
         *        }
11226.
         *      } );
11227.
         *    } );
11228.
         */
11229.
        "iDeferLoading": null,
11230.
    
11231.
    
11232.
        /**
11233.
         * Number of rows to display on a single page when using pagination. If
11234.
         * feature enabled (`lengthChange`) then the end user will be able to override
11235.
         * this to a custom setting using a pop-up menu.
11236.
         *  @type int
11237.
         *  @default 10
11238.
         *
11239.
         *  @dtopt Options
11240.
         *  @name DataTable.defaults.pageLength
11241.
         *
11242.
         *  @example
11243.
         *    $(document).ready( function() {
11244.
         *      $('#example').dataTable( {
11245.
         *        "pageLength": 50
11246.
         *      } );
11247.
         *    } )
11248.
         */
11249.
        "iDisplayLength": 10,
11250.
    
11251.
    
11252.
        /**
11253.
         * Define the starting point for data display when using DataTables with
11254.
         * pagination. Note that this parameter is the number of records, rather than
11255.
         * the page number, so if you have 10 records per page and want to start on
11256.
         * the third page, it should be "20".
11257.
         *  @type int
11258.
         *  @default 0
11259.
         *
11260.
         *  @dtopt Options
11261.
         *  @name DataTable.defaults.displayStart
11262.
         *
11263.
         *  @example
11264.
         *    $(document).ready( function() {
11265.
         *      $('#example').dataTable( {
11266.
         *        "displayStart": 20
11267.
         *      } );
11268.
         *    } )
11269.
         */
11270.
        "iDisplayStart": 0,
11271.
    
11272.
    
11273.
        /**
11274.
         * By default DataTables allows keyboard navigation of the table (sorting, paging,
11275.
         * and filtering) by adding a `tabindex` attribute to the required elements. This
11276.
         * allows you to tab through the controls and press the enter key to activate them.
11277.
         * The tabindex is default 0, meaning that the tab follows the flow of the document.
11278.
         * You can overrule this using this parameter if you wish. Use a value of -1 to
11279.
         * disable built-in keyboard navigation.
11280.
         *  @type int
11281.
         *  @default 0
11282.
         *
11283.
         *  @dtopt Options
11284.
         *  @name DataTable.defaults.tabIndex
11285.
         *
11286.
         *  @example
11287.
         *    $(document).ready( function() {
11288.
         *      $('#example').dataTable( {
11289.
         *        "tabIndex": 1
11290.
         *      } );
11291.
         *    } );
11292.
         */
11293.
        "iTabIndex": 0,
11294.
    
11295.
    
11296.
        /**
11297.
         * Classes that DataTables assigns to the various components and features
11298.
         * that it adds to the HTML table. This allows classes to be configured
11299.
         * during initialisation in addition to through the static
11300.
         * {@link DataTable.ext.oStdClasses} object).
11301.
         *  @namespace
11302.
         *  @name DataTable.defaults.classes
11303.
         */
11304.
        "oClasses": {},
11305.
    
11306.
    
11307.
        /**
11308.
         * All strings that DataTables uses in the user interface that it creates
11309.
         * are defined in this object, allowing you to modified them individually or
11310.
         * completely replace them all as required.
11311.
         *  @namespace
11312.
         *  @name DataTable.defaults.language
11313.
         */
11314.
        "oLanguage": {
11315.
            /**
11316.
             * Strings that are used for WAI-ARIA labels and controls only (these are not
11317.
             * actually visible on the page, but will be read by screenreaders, and thus
11318.
             * must be internationalised as well).
11319.
             *  @namespace
11320.
             *  @name DataTable.defaults.language.aria
11321.
             */
11322.
            "oAria": {
11323.
                /**
11324.
                 * ARIA label that is added to the table headers when the column may be
11325.
                 * sorted ascending by activing the column (click or return when focused).
11326.
                 * Note that the column header is prefixed to this string.
11327.
                 *  @type string
11328.
                 *  @default : activate to sort column ascending
11329.
                 *
11330.
                 *  @dtopt Language
11331.
                 *  @name DataTable.defaults.language.aria.sortAscending
11332.
                 *
11333.
                 *  @example
11334.
                 *    $(document).ready( function() {
11335.
                 *      $('#example').dataTable( {
11336.
                 *        "language": {
11337.
                 *          "aria": {
11338.
                 *            "sortAscending": " - click/return to sort ascending"
11339.
                 *          }
11340.
                 *        }
11341.
                 *      } );
11342.
                 *    } );
11343.
                 */
11344.
                "sSortAscending": ": activate to sort column ascending",
11345.
    
11346.
                /**
11347.
                 * ARIA label that is added to the table headers when the column may be
11348.
                 * sorted descending by activing the column (click or return when focused).
11349.
                 * Note that the column header is prefixed to this string.
11350.
                 *  @type string
11351.
                 *  @default : activate to sort column ascending
11352.
                 *
11353.
                 *  @dtopt Language
11354.
                 *  @name DataTable.defaults.language.aria.sortDescending
11355.
                 *
11356.
                 *  @example
11357.
                 *    $(document).ready( function() {
11358.
                 *      $('#example').dataTable( {
11359.
                 *        "language": {
11360.
                 *          "aria": {
11361.
                 *            "sortDescending": " - click/return to sort descending"
11362.
                 *          }
11363.
                 *        }
11364.
                 *      } );
11365.
                 *    } );
11366.
                 */
11367.
                "sSortDescending": ": activate to sort column descending"
11368.
            },
11369.
    
11370.
            /**
11371.
             * Pagination string used by DataTables for the built-in pagination
11372.
             * control types.
11373.
             *  @namespace
11374.
             *  @name DataTable.defaults.language.paginate
11375.
             */
11376.
            "oPaginate": {
11377.
                /**
11378.
                 * Text to use when using the 'full_numbers' type of pagination for the
11379.
                 * button to take the user to the first page.
11380.
                 *  @type string
11381.
                 *  @default First
11382.
                 *
11383.
                 *  @dtopt Language
11384.
                 *  @name DataTable.defaults.language.paginate.first
11385.
                 *
11386.
                 *  @example
11387.
                 *    $(document).ready( function() {
11388.
                 *      $('#example').dataTable( {
11389.
                 *        "language": {
11390.
                 *          "paginate": {
11391.
                 *            "first": "First page"
11392.
                 *          }
11393.
                 *        }
11394.
                 *      } );
11395.
                 *    } );
11396.
                 */
11397.
                "sFirst": "First",
11398.
    
11399.
    
11400.
                /**
11401.
                 * Text to use when using the 'full_numbers' type of pagination for the
11402.
                 * button to take the user to the last page.
11403.
                 *  @type string
11404.
                 *  @default Last
11405.
                 *
11406.
                 *  @dtopt Language
11407.
                 *  @name DataTable.defaults.language.paginate.last
11408.
                 *
11409.
                 *  @example
11410.
                 *    $(document).ready( function() {
11411.
                 *      $('#example').dataTable( {
11412.
                 *        "language": {
11413.
                 *          "paginate": {
11414.
                 *            "last": "Last page"
11415.
                 *          }
11416.
                 *        }
11417.
                 *      } );
11418.
                 *    } );
11419.
                 */
11420.
                "sLast": "Last",
11421.
    
11422.
    
11423.
                /**
11424.
                 * Text to use for the 'next' pagination button (to take the user to the
11425.
                 * next page).
11426.
                 *  @type string
11427.
                 *  @default Next
11428.
                 *
11429.
                 *  @dtopt Language
11430.
                 *  @name DataTable.defaults.language.paginate.next
11431.
                 *
11432.
                 *  @example
11433.
                 *    $(document).ready( function() {
11434.
                 *      $('#example').dataTable( {
11435.
                 *        "language": {
11436.
                 *          "paginate": {
11437.
                 *            "next": "Next page"
11438.
                 *          }
11439.
                 *        }
11440.
                 *      } );
11441.
                 *    } );
11442.
                 */
11443.
                "sNext": "Next",
11444.
    
11445.
    
11446.
                /**
11447.
                 * Text to use for the 'previous' pagination button (to take the user to
11448.
                 * the previous page).
11449.
                 *  @type string
11450.
                 *  @default Previous
11451.
                 *
11452.
                 *  @dtopt Language
11453.
                 *  @name DataTable.defaults.language.paginate.previous
11454.
                 *
11455.
                 *  @example
11456.
                 *    $(document).ready( function() {
11457.
                 *      $('#example').dataTable( {
11458.
                 *        "language": {
11459.
                 *          "paginate": {
11460.
                 *            "previous": "Previous page"
11461.
                 *          }
11462.
                 *        }
11463.
                 *      } );
11464.
                 *    } );
11465.
                 */
11466.
                "sPrevious": "Previous"
11467.
            },
11468.
    
11469.
            /**
11470.
             * This string is shown in preference to `zeroRecords` when the table is
11471.
             * empty of data (regardless of filtering). Note that this is an optional
11472.
             * parameter - if it is not given, the value of `zeroRecords` will be used
11473.
             * instead (either the default or given value).
11474.
             *  @type string
11475.
             *  @default No data available in table
11476.
             *
11477.
             *  @dtopt Language
11478.
             *  @name DataTable.defaults.language.emptyTable
11479.
             *
11480.
             *  @example
11481.
             *    $(document).ready( function() {
11482.
             *      $('#example').dataTable( {
11483.
             *        "language": {
11484.
             *          "emptyTable": "No data available in table"
11485.
             *        }
11486.
             *      } );
11487.
             *    } );
11488.
             */
11489.
            "sEmptyTable": "No data available in table",
11490.
    
11491.
    
11492.
            /**
11493.
             * This string gives information to the end user about the information
11494.
             * that is current on display on the page. The following tokens can be
11495.
             * used in the string and will be dynamically replaced as the table
11496.
             * display updates. This tokens can be placed anywhere in the string, or
11497.
             * removed as needed by the language requires:
11498.
             *
11499.
             * * `\_START\_` - Display index of the first record on the current page
11500.
             * * `\_END\_` - Display index of the last record on the current page
11501.
             * * `\_TOTAL\_` - Number of records in the table after filtering
11502.
             * * `\_MAX\_` - Number of records in the table without filtering
11503.
             * * `\_PAGE\_` - Current page number
11504.
             * * `\_PAGES\_` - Total number of pages of data in the table
11505.
             *
11506.
             *  @type string
11507.
             *  @default Showing _START_ to _END_ of _TOTAL_ entries
11508.
             *
11509.
             *  @dtopt Language
11510.
             *  @name DataTable.defaults.language.info
11511.
             *
11512.
             *  @example
11513.
             *    $(document).ready( function() {
11514.
             *      $('#example').dataTable( {
11515.
             *        "language": {
11516.
             *          "info": "Showing page _PAGE_ of _PAGES_"
11517.
             *        }
11518.
             *      } );
11519.
             *    } );
11520.
             */
11521.
            "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11522.
    
11523.
    
11524.
            /**
11525.
             * Display information string for when the table is empty. Typically the
11526.
             * format of this string should match `info`.
11527.
             *  @type string
11528.
             *  @default Showing 0 to 0 of 0 entries
11529.
             *
11530.
             *  @dtopt Language
11531.
             *  @name DataTable.defaults.language.infoEmpty
11532.
             *
11533.
             *  @example
11534.
             *    $(document).ready( function() {
11535.
             *      $('#example').dataTable( {
11536.
             *        "language": {
11537.
             *          "infoEmpty": "No entries to show"
11538.
             *        }
11539.
             *      } );
11540.
             *    } );
11541.
             */
11542.
            "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11543.
    
11544.
    
11545.
            /**
11546.
             * When a user filters the information in a table, this string is appended
11547.
             * to the information (`info`) to give an idea of how strong the filtering
11548.
             * is. The variable _MAX_ is dynamically updated.
11549.
             *  @type string
11550.
             *  @default (filtered from _MAX_ total entries)
11551.
             *
11552.
             *  @dtopt Language
11553.
             *  @name DataTable.defaults.language.infoFiltered
11554.
             *
11555.
             *  @example
11556.
             *    $(document).ready( function() {
11557.
             *      $('#example').dataTable( {
11558.
             *        "language": {
11559.
             *          "infoFiltered": " - filtering from _MAX_ records"
11560.
             *        }
11561.
             *      } );
11562.
             *    } );
11563.
             */
11564.
            "sInfoFiltered": "(filtered from _MAX_ total entries)",
11565.
    
11566.
    
11567.
            /**
11568.
             * If can be useful to append extra information to the info string at times,
11569.
             * and this variable does exactly that. This information will be appended to
11570.
             * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11571.
             * being used) at all times.
11572.
             *  @type string
11573.
             *  @default <i>Empty string</i>
11574.
             *
11575.
             *  @dtopt Language
11576.
             *  @name DataTable.defaults.language.infoPostFix
11577.
             *
11578.
             *  @example
11579.
             *    $(document).ready( function() {
11580.
             *      $('#example').dataTable( {
11581.
             *        "language": {
11582.
             *          "infoPostFix": "All records shown are derived from real information."
11583.
             *        }
11584.
             *      } );
11585.
             *    } );
11586.
             */
11587.
            "sInfoPostFix": "",
11588.
    
11589.
    
11590.
            /**
11591.
             * This decimal place operator is a little different from the other
11592.
             * language options since DataTables doesn't output floating point
11593.
             * numbers, so it won't ever use this for display of a number. Rather,
11594.
             * what this parameter does is modify the sort methods of the table so
11595.
             * that numbers which are in a format which has a character other than
11596.
             * a period (`.`) as a decimal place will be sorted numerically.
11597.
             *
11598.
             * Note that numbers with different decimal places cannot be shown in
11599.
             * the same table and still be sortable, the table must be consistent.
11600.
             * However, multiple different tables on the page can use different
11601.
             * decimal place characters.
11602.
             *  @type string
11603.
             *  @default 
11604.
             *
11605.
             *  @dtopt Language
11606.
             *  @name DataTable.defaults.language.decimal
11607.
             *
11608.
             *  @example
11609.
             *    $(document).ready( function() {
11610.
             *      $('#example').dataTable( {
11611.
             *        "language": {
11612.
             *          "decimal": ","
11613.
             *          "thousands": "."
11614.
             *        }
11615.
             *      } );
11616.
             *    } );
11617.
             */
11618.
            "sDecimal": "",
11619.
    
11620.
    
11621.
            /**
11622.
             * DataTables has a build in number formatter (`formatNumber`) which is
11623.
             * used to format large numbers that are used in the table information.
11624.
             * By default a comma is used, but this can be trivially changed to any
11625.
             * character you wish with this parameter.
11626.
             *  @type string
11627.
             *  @default ,
11628.
             *
11629.
             *  @dtopt Language
11630.
             *  @name DataTable.defaults.language.thousands
11631.
             *
11632.
             *  @example
11633.
             *    $(document).ready( function() {
11634.
             *      $('#example').dataTable( {
11635.
             *        "language": {
11636.
             *          "thousands": "'"
11637.
             *        }
11638.
             *      } );
11639.
             *    } );
11640.
             */
11641.
            "sThousands": ",",
11642.
    
11643.
    
11644.
            /**
11645.
             * Detail the action that will be taken when the drop down menu for the
11646.
             * pagination length option is changed. The '_MENU_' variable is replaced
11647.
             * with a default select list of 10, 25, 50 and 100, and can be replaced
11648.
             * with a custom select box if required.
11649.
             *  @type string
11650.
             *  @default Show _MENU_ entries
11651.
             *
11652.
             *  @dtopt Language
11653.
             *  @name DataTable.defaults.language.lengthMenu
11654.
             *
11655.
             *  @example
11656.
             *    // Language change only
11657.
             *    $(document).ready( function() {
11658.
             *      $('#example').dataTable( {
11659.
             *        "language": {
11660.
             *          "lengthMenu": "Display _MENU_ records"
11661.
             *        }
11662.
             *      } );
11663.
             *    } );
11664.
             *
11665.
             *  @example
11666.
             *    // Language and options change
11667.
             *    $(document).ready( function() {
11668.
             *      $('#example').dataTable( {
11669.
             *        "language": {
11670.
             *          "lengthMenu": 'Display <select>'+
11671.
             *            '<option value="10">10</option>'+
11672.
             *            '<option value="20">20</option>'+
11673.
             *            '<option value="30">30</option>'+
11674.
             *            '<option value="40">40</option>'+
11675.
             *            '<option value="50">50</option>'+
11676.
             *            '<option value="-1">All</option>'+
11677.
             *            '</select> records'
11678.
             *        }
11679.
             *      } );
11680.
             *    } );
11681.
             */
11682.
            "sLengthMenu": "Show _MENU_ entries",
11683.
    
11684.
    
11685.
            /**
11686.
             * When using Ajax sourced data and during the first draw when DataTables is
11687.
             * gathering the data, this message is shown in an empty row in the table to
11688.
             * indicate to the end user the the data is being loaded. Note that this
11689.
             * parameter is not used when loading data by server-side processing, just
11690.
             * Ajax sourced data with client-side processing.
11691.
             *  @type string
11692.
             *  @default Loading...
11693.
             *
11694.
             *  @dtopt Language
11695.
             *  @name DataTable.defaults.language.loadingRecords
11696.
             *
11697.
             *  @example
11698.
             *    $(document).ready( function() {
11699.
             *      $('#example').dataTable( {
11700.
             *        "language": {
11701.
             *          "loadingRecords": "Please wait - loading..."
11702.
             *        }
11703.
             *      } );
11704.
             *    } );
11705.
             */
11706.
            "sLoadingRecords": "Loading...",
11707.
    
11708.
    
11709.
            /**
11710.
             * Text which is displayed when the table is processing a user action
11711.
             * (usually a sort command or similar).
11712.
             *  @type string
11713.
             *  @default Processing...
11714.
             *
11715.
             *  @dtopt Language
11716.
             *  @name DataTable.defaults.language.processing
11717.
             *
11718.
             *  @example
11719.
             *    $(document).ready( function() {
11720.
             *      $('#example').dataTable( {
11721.
             *        "language": {
11722.
             *          "processing": "DataTables is currently busy"
11723.
             *        }
11724.
             *      } );
11725.
             *    } );
11726.
             */
11727.
            "sProcessing": "Processing...",
11728.
    
11729.
    
11730.
            /**
11731.
             * Details the actions that will be taken when the user types into the
11732.
             * filtering input text box. The variable "_INPUT_", if used in the string,
11733.
             * is replaced with the HTML text box for the filtering input allowing
11734.
             * control over where it appears in the string. If "_INPUT_" is not given
11735.
             * then the input box is appended to the string automatically.
11736.
             *  @type string
11737.
             *  @default Search:
11738.
             *
11739.
             *  @dtopt Language
11740.
             *  @name DataTable.defaults.language.search
11741.
             *
11742.
             *  @example
11743.
             *    // Input text box will be appended at the end automatically
11744.
             *    $(document).ready( function() {
11745.
             *      $('#example').dataTable( {
11746.
             *        "language": {
11747.
             *          "search": "Filter records:"
11748.
             *        }
11749.
             *      } );
11750.
             *    } );
11751.
             *
11752.
             *  @example
11753.
             *    // Specify where the filter should appear
11754.
             *    $(document).ready( function() {
11755.
             *      $('#example').dataTable( {
11756.
             *        "language": {
11757.
             *          "search": "Apply filter _INPUT_ to table"
11758.
             *        }
11759.
             *      } );
11760.
             *    } );
11761.
             */
11762.
            "sSearch": "Search:",
11763.
    
11764.
    
11765.
            /**
11766.
             * Assign a `placeholder` attribute to the search `input` element
11767.
             *  @type string
11768.
             *  @default 
11769.
             *
11770.
             *  @dtopt Language
11771.
             *  @name DataTable.defaults.language.searchPlaceholder
11772.
             */
11773.
            "sSearchPlaceholder": "",
11774.
    
11775.
    
11776.
            /**
11777.
             * All of the language information can be stored in a file on the
11778.
             * server-side, which DataTables will look up if this parameter is passed.
11779.
             * It must store the URL of the language file, which is in a JSON format,
11780.
             * and the object has the same properties as the oLanguage object in the
11781.
             * initialiser object (i.e. the above parameters). Please refer to one of
11782.
             * the example language files to see how this works in action.
11783.
             *  @type string
11784.
             *  @default <i>Empty string - i.e. disabled</i>
11785.
             *
11786.
             *  @dtopt Language
11787.
             *  @name DataTable.defaults.language.url
11788.
             *
11789.
             *  @example
11790.
             *    $(document).ready( function() {
11791.
             *      $('#example').dataTable( {
11792.
             *        "language": {
11793.
             *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11794.
             *        }
11795.
             *      } );
11796.
             *    } );
11797.
             */
11798.
            "sUrl": "",
11799.
    
11800.
    
11801.
            /**
11802.
             * Text shown inside the table records when the is no information to be
11803.
             * displayed after filtering. `emptyTable` is shown when there is simply no
11804.
             * information in the table at all (regardless of filtering).
11805.
             *  @type string
11806.
             *  @default No matching records found
11807.
             *
11808.
             *  @dtopt Language
11809.
             *  @name DataTable.defaults.language.zeroRecords
11810.
             *
11811.
             *  @example
11812.
             *    $(document).ready( function() {
11813.
             *      $('#example').dataTable( {
11814.
             *        "language": {
11815.
             *          "zeroRecords": "No records to display"
11816.
             *        }
11817.
             *      } );
11818.
             *    } );
11819.
             */
11820.
            "sZeroRecords": "No matching records found"
11821.
        },
11822.
    
11823.
    
11824.
        /**
11825.
         * This parameter allows you to have define the global filtering state at
11826.
         * initialisation time. As an object the `search` parameter must be
11827.
         * defined, but all other parameters are optional. When `regex` is true,
11828.
         * the search string will be treated as a regular expression, when false
11829.
         * (default) it will be treated as a straight string. When `smart`
11830.
         * DataTables will use it's smart filtering methods (to word match at
11831.
         * any point in the data), when false this will not be done.
11832.
         *  @namespace
11833.
         *  @extends DataTable.models.oSearch
11834.
         *
11835.
         *  @dtopt Options
11836.
         *  @name DataTable.defaults.search
11837.
         *
11838.
         *  @example
11839.
         *    $(document).ready( function() {
11840.
         *      $('#example').dataTable( {
11841.
         *        "search": {"search": "Initial search"}
11842.
         *      } );
11843.
         *    } )
11844.
         */
11845.
        "oSearch": $.extend( {}, DataTable.models.oSearch ),
11846.
    
11847.
    
11848.
        /**
11849.
         * __Deprecated__ The functionality provided by this parameter has now been
11850.
         * superseded by that provided through `ajax`, which should be used instead.
11851.
         *
11852.
         * By default DataTables will look for the property `data` (or `aaData` for
11853.
         * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11854.
         * source or for server-side processing - this parameter allows that
11855.
         * property to be changed. You can use Javascript dotted object notation to
11856.
         * get a data source for multiple levels of nesting.
11857.
         *  @type string
11858.
         *  @default data
11859.
         *
11860.
         *  @dtopt Options
11861.
         *  @dtopt Server-side
11862.
         *  @name DataTable.defaults.ajaxDataProp
11863.
         *
11864.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
11865.
         */
11866.
        "sAjaxDataProp": "data",
11867.
    
11868.
    
11869.
        /**
11870.
         * __Deprecated__ The functionality provided by this parameter has now been
11871.
         * superseded by that provided through `ajax`, which should be used instead.
11872.
         *
11873.
         * You can instruct DataTables to load data from an external
11874.
         * source using this parameter (use aData if you want to pass data in you
11875.
         * already have). Simply provide a url a JSON object can be obtained from.
11876.
         *  @type string
11877.
         *  @default null
11878.
         *
11879.
         *  @dtopt Options
11880.
         *  @dtopt Server-side
11881.
         *  @name DataTable.defaults.ajaxSource
11882.
         *
11883.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
11884.
         */
11885.
        "sAjaxSource": null,
11886.
    
11887.
    
11888.
        /**
11889.
         * This initialisation variable allows you to specify exactly where in the
11890.
         * DOM you want DataTables to inject the various controls it adds to the page
11891.
         * (for example you might want the pagination controls at the top of the
11892.
         * table). DIV elements (with or without a custom class) can also be added to
11893.
         * aid styling. The follow syntax is used:
11894.
         *   <ul>
11895.
         *     <li>The following options are allowed:
11896.
         *       <ul>
11897.
         *         <li>'l' - Length changing</li>
11898.
         *         <li>'f' - Filtering input</li>
11899.
         *         <li>'t' - The table!</li>
11900.
         *         <li>'i' - Information</li>
11901.
         *         <li>'p' - Pagination</li>
11902.
         *         <li>'r' - pRocessing</li>
11903.
         *       </ul>
11904.
         *     </li>
11905.
         *     <li>The following constants are allowed:
11906.
         *       <ul>
11907.
         *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11908.
         *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11909.
         *       </ul>
11910.
         *     </li>
11911.
         *     <li>The following syntax is expected:
11912.
         *       <ul>
11913.
         *         <li>'&lt;' and '&gt;' - div elements</li>
11914.
         *         <li>'&lt;"class" and '&gt;' - div with a class</li>
11915.
         *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11916.
         *       </ul>
11917.
         *     </li>
11918.
         *     <li>Examples:
11919.
         *       <ul>
11920.
         *         <li>'&lt;"wrapper"flipt&gt;'</li>
11921.
         *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11922.
         *       </ul>
11923.
         *     </li>
11924.
         *   </ul>
11925.
         *  @type string
11926.
         *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11927.
         *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11928.
         *
11929.
         *  @dtopt Options
11930.
         *  @name DataTable.defaults.dom
11931.
         *
11932.
         *  @example
11933.
         *    $(document).ready( function() {
11934.
         *      $('#example').dataTable( {
11935.
         *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11936.
         *      } );
11937.
         *    } );
11938.
         */
11939.
        "sDom": "lfrtip",
11940.
    
11941.
    
11942.
        /**
11943.
         * Search delay option. This will throttle full table searches that use the
11944.
         * DataTables provided search input element (it does not effect calls to
11945.
         * `dt-api search()`, providing a delay before the search is made.
11946.
         *  @type integer
11947.
         *  @default 0
11948.
         *
11949.
         *  @dtopt Options
11950.
         *  @name DataTable.defaults.searchDelay
11951.
         *
11952.
         *  @example
11953.
         *    $(document).ready( function() {
11954.
         *      $('#example').dataTable( {
11955.
         *        "searchDelay": 200
11956.
         *      } );
11957.
         *    } )
11958.
         */
11959.
        "searchDelay": null,
11960.
    
11961.
    
11962.
        /**
11963.
         * DataTables features six different built-in options for the buttons to
11964.
         * display for pagination control:
11965.
         *
11966.
         * * `numbers` - Page number buttons only
11967.
         * * `simple` - 'Previous' and 'Next' buttons only
11968.
         * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11969.
         * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11970.
         * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11971.
         * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11972.
         *  
11973.
         * Further methods can be added using {@link DataTable.ext.oPagination}.
11974.
         *  @type string
11975.
         *  @default simple_numbers
11976.
         *
11977.
         *  @dtopt Options
11978.
         *  @name DataTable.defaults.pagingType
11979.
         *
11980.
         *  @example
11981.
         *    $(document).ready( function() {
11982.
         *      $('#example').dataTable( {
11983.
         *        "pagingType": "full_numbers"
11984.
         *      } );
11985.
         *    } )
11986.
         */
11987.
        "sPaginationType": "simple_numbers",
11988.
    
11989.
    
11990.
        /**
11991.
         * Enable horizontal scrolling. When a table is too wide to fit into a
11992.
         * certain layout, or you have a large number of columns in the table, you
11993.
         * can enable x-scrolling to show the table in a viewport, which can be
11994.
         * scrolled. This property can be `true` which will allow the table to
11995.
         * scroll horizontally when needed, or any CSS unit, or a number (in which
11996.
         * case it will be treated as a pixel measurement). Setting as simply `true`
11997.
         * is recommended.
11998.
         *  @type boolean|string
11999.
         *  @default <i>blank string - i.e. disabled</i>
12000.
         *
12001.
         *  @dtopt Features
12002.
         *  @name DataTable.defaults.scrollX
12003.
         *
12004.
         *  @example
12005.
         *    $(document).ready( function() {
12006.
         *      $('#example').dataTable( {
12007.
         *        "scrollX": true,
12008.
         *        "scrollCollapse": true
12009.
         *      } );
12010.
         *    } );
12011.
         */
12012.
        "sScrollX": "",
12013.
    
12014.
    
12015.
        /**
12016.
         * This property can be used to force a DataTable to use more width than it
12017.
         * might otherwise do when x-scrolling is enabled. For example if you have a
12018.
         * table which requires to be well spaced, this parameter is useful for
12019.
         * "over-sizing" the table, and thus forcing scrolling. This property can by
12020.
         * any CSS unit, or a number (in which case it will be treated as a pixel
12021.
         * measurement).
12022.
         *  @type string
12023.
         *  @default <i>blank string - i.e. disabled</i>
12024.
         *
12025.
         *  @dtopt Options
12026.
         *  @name DataTable.defaults.scrollXInner
12027.
         *
12028.
         *  @example
12029.
         *    $(document).ready( function() {
12030.
         *      $('#example').dataTable( {
12031.
         *        "scrollX": "100%",
12032.
         *        "scrollXInner": "110%"
12033.
         *      } );
12034.
         *    } );
12035.
         */
12036.
        "sScrollXInner": "",
12037.
    
12038.
    
12039.
        /**
12040.
         * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
12041.
         * to the given height, and enable scrolling for any data which overflows the
12042.
         * current viewport. This can be used as an alternative to paging to display
12043.
         * a lot of data in a small area (although paging and scrolling can both be
12044.
         * enabled at the same time). This property can be any CSS unit, or a number
12045.
         * (in which case it will be treated as a pixel measurement).
12046.
         *  @type string
12047.
         *  @default <i>blank string - i.e. disabled</i>
12048.
         *
12049.
         *  @dtopt Features
12050.
         *  @name DataTable.defaults.scrollY
12051.
         *
12052.
         *  @example
12053.
         *    $(document).ready( function() {
12054.
         *      $('#example').dataTable( {
12055.
         *        "scrollY": "200px",
12056.
         *        "paginate": false
12057.
         *      } );
12058.
         *    } );
12059.
         */
12060.
        "sScrollY": "",
12061.
    
12062.
    
12063.
        /**
12064.
         * __Deprecated__ The functionality provided by this parameter has now been
12065.
         * superseded by that provided through `ajax`, which should be used instead.
12066.
         *
12067.
         * Set the HTTP method that is used to make the Ajax call for server-side
12068.
         * processing or Ajax sourced data.
12069.
         *  @type string
12070.
         *  @default GET
12071.
         *
12072.
         *  @dtopt Options
12073.
         *  @dtopt Server-side
12074.
         *  @name DataTable.defaults.serverMethod
12075.
         *
12076.
         *  @deprecated 1.10. Please use `ajax` for this functionality now.
12077.
         */
12078.
        "sServerMethod": "GET",
12079.
    
12080.
    
12081.
        /**
12082.
         * DataTables makes use of renderers when displaying HTML elements for
12083.
         * a table. These renderers can be added or modified by plug-ins to
12084.
         * generate suitable mark-up for a site. For example the Bootstrap
12085.
         * integration plug-in for DataTables uses a paging button renderer to
12086.
         * display pagination buttons in the mark-up required by Bootstrap.
12087.
         *
12088.
         * For further information about the renderers available see
12089.
         * DataTable.ext.renderer
12090.
         *  @type string|object
12091.
         *  @default null
12092.
         *
12093.
         *  @name DataTable.defaults.renderer
12094.
         *
12095.
         */
12096.
        "renderer": null,
12097.
    
12098.
    
12099.
        /**
12100.
         * Set the data property name that DataTables should use to get a row's id
12101.
         * to set as the `id` property in the node.
12102.
         *  @type string
12103.
         *  @default DT_RowId
12104.
         *
12105.
         *  @name DataTable.defaults.rowId
12106.
         */
12107.
        "rowId": "DT_RowId"
12108.
    };
12109.
    
12110.
    _fnHungarianMap( DataTable.defaults );
12111.
    
12112.
    
12113.
    
12114.
    /*
12115.
     * Developer note - See note in model.defaults.js about the use of Hungarian
12116.
     * notation and camel case.
12117.
     */
12118.
    
12119.
    /**
12120.
     * Column options that can be given to DataTables at initialisation time.
12121.
     *  @namespace
12122.
     */
12123.
    DataTable.defaults.column = {
12124.
        /**
12125.
         * Define which column(s) an order will occur on for this column. This
12126.
         * allows a column's ordering to take multiple columns into account when
12127.
         * doing a sort or use the data from a different column. For example first
12128.
         * name / last name columns make sense to do a multi-column sort over the
12129.
         * two columns.
12130.
         *  @type array|int
12131.
         *  @default null <i>Takes the value of the column index automatically</i>
12132.
         *
12133.
         *  @name DataTable.defaults.column.orderData
12134.
         *  @dtopt Columns
12135.
         *
12136.
         *  @example
12137.
         *    // Using `columnDefs`
12138.
         *    $(document).ready( function() {
12139.
         *      $('#example').dataTable( {
12140.
         *        "columnDefs": [
12141.
         *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
12142.
         *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
12143.
         *          { "orderData": 2, "targets": [ 2 ] }
12144.
         *        ]
12145.
         *      } );
12146.
         *    } );
12147.
         *
12148.
         *  @example
12149.
         *    // Using `columns`
12150.
         *    $(document).ready( function() {
12151.
         *      $('#example').dataTable( {
12152.
         *        "columns": [
12153.
         *          { "orderData": [ 0, 1 ] },
12154.
         *          { "orderData": [ 1, 0 ] },
12155.
         *          { "orderData": 2 },
12156.
         *          null,
12157.
         *          null
12158.
         *        ]
12159.
         *      } );
12160.
         *    } );
12161.
         */
12162.
        "aDataSort": null,
12163.
        "iDataSort": -1,
12164.
    
12165.
    
12166.
        /**
12167.
         * You can control the default ordering direction, and even alter the
12168.
         * behaviour of the sort handler (i.e. only allow ascending ordering etc)
12169.
         * using this parameter.
12170.
         *  @type array
12171.
         *  @default [ 'asc', 'desc' ]
12172.
         *
12173.
         *  @name DataTable.defaults.column.orderSequence
12174.
         *  @dtopt Columns
12175.
         *
12176.
         *  @example
12177.
         *    // Using `columnDefs`
12178.
         *    $(document).ready( function() {
12179.
         *      $('#example').dataTable( {
12180.
         *        "columnDefs": [
12181.
         *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
12182.
         *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
12183.
         *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
12184.
         *        ]
12185.
         *      } );
12186.
         *    } );
12187.
         *
12188.
         *  @example
12189.
         *    // Using `columns`
12190.
         *    $(document).ready( function() {
12191.
         *      $('#example').dataTable( {
12192.
         *        "columns": [
12193.
         *          null,
12194.
         *          { "orderSequence": [ "asc" ] },
12195.
         *          { "orderSequence": [ "desc", "asc", "asc" ] },
12196.
         *          { "orderSequence": [ "desc" ] },
12197.
         *          null
12198.
         *        ]
12199.
         *      } );
12200.
         *    } );
12201.
         */
12202.
        "asSorting": [ 'asc', 'desc' ],
12203.
    
12204.
    
12205.
        /**
12206.
         * Enable or disable filtering on the data in this column.
12207.
         *  @type boolean
12208.
         *  @default true
12209.
         *
12210.
         *  @name DataTable.defaults.column.searchable
12211.
         *  @dtopt Columns
12212.
         *
12213.
         *  @example
12214.
         *    // Using `columnDefs`
12215.
         *    $(document).ready( function() {
12216.
         *      $('#example').dataTable( {
12217.
         *        "columnDefs": [
12218.
         *          { "searchable": false, "targets": [ 0 ] }
12219.
         *        ] } );
12220.
         *    } );
12221.
         *
12222.
         *  @example
12223.
         *    // Using `columns`
12224.
         *    $(document).ready( function() {
12225.
         *      $('#example').dataTable( {
12226.
         *        "columns": [
12227.
         *          { "searchable": false },
12228.
         *          null,
12229.
         *          null,
12230.
         *          null,
12231.
         *          null
12232.
         *        ] } );
12233.
         *    } );
12234.
         */
12235.
        "bSearchable": true,
12236.
    
12237.
    
12238.
        /**
12239.
         * Enable or disable ordering on this column.
12240.
         *  @type boolean
12241.
         *  @default true
12242.
         *
12243.
         *  @name DataTable.defaults.column.orderable
12244.
         *  @dtopt Columns
12245.
         *
12246.
         *  @example
12247.
         *    // Using `columnDefs`
12248.
         *    $(document).ready( function() {
12249.
         *      $('#example').dataTable( {
12250.
         *        "columnDefs": [
12251.
         *          { "orderable": false, "targets": [ 0 ] }
12252.
         *        ] } );
12253.
         *    } );
12254.
         *
12255.
         *  @example
12256.
         *    // Using `columns`
12257.
         *    $(document).ready( function() {
12258.
         *      $('#example').dataTable( {
12259.
         *        "columns": [
12260.
         *          { "orderable": false },
12261.
         *          null,
12262.
         *          null,
12263.
         *          null,
12264.
         *          null
12265.
         *        ] } );
12266.
         *    } );
12267.
         */
12268.
        "bSortable": true,
12269.
    
12270.
    
12271.
        /**
12272.
         * Enable or disable the display of this column.
12273.
         *  @type boolean
12274.
         *  @default true
12275.
         *
12276.
         *  @name DataTable.defaults.column.visible
12277.
         *  @dtopt Columns
12278.
         *
12279.
         *  @example
12280.
         *    // Using `columnDefs`
12281.
         *    $(document).ready( function() {
12282.
         *      $('#example').dataTable( {
12283.
         *        "columnDefs": [
12284.
         *          { "visible": false, "targets": [ 0 ] }
12285.
         *        ] } );
12286.
         *    } );
12287.
         *
12288.
         *  @example
12289.
         *    // Using `columns`
12290.
         *    $(document).ready( function() {
12291.
         *      $('#example').dataTable( {
12292.
         *        "columns": [
12293.
         *          { "visible": false },
12294.
         *          null,
12295.
         *          null,
12296.
         *          null,
12297.
         *          null
12298.
         *        ] } );
12299.
         *    } );
12300.
         */
12301.
        "bVisible": true,
12302.
    
12303.
    
12304.
        /**
12305.
         * Developer definable function that is called whenever a cell is created (Ajax source,
12306.
         * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12307.
         * allowing you to modify the DOM element (add background colour for example) when the
12308.
         * element is available.
12309.
         *  @type function
12310.
         *  @param {element} td The TD node that has been created
12311.
         *  @param {*} cellData The Data for the cell
12312.
         *  @param {array|object} rowData The data for the whole row
12313.
         *  @param {int} row The row index for the aoData data store
12314.
         *  @param {int} col The column index for aoColumns
12315.
         *
12316.
         *  @name DataTable.defaults.column.createdCell
12317.
         *  @dtopt Columns
12318.
         *
12319.
         *  @example
12320.
         *    $(document).ready( function() {
12321.
         *      $('#example').dataTable( {
12322.
         *        "columnDefs": [ {
12323.
         *          "targets": [3],
12324.
         *          "createdCell": function (td, cellData, rowData, row, col) {
12325.
         *            if ( cellData == "1.7" ) {
12326.
         *              $(td).css('color', 'blue')
12327.
         *            }
12328.
         *          }
12329.
         *        } ]
12330.
         *      });
12331.
         *    } );
12332.
         */
12333.
        "fnCreatedCell": null,
12334.
    
12335.
    
12336.
        /**
12337.
         * This parameter has been replaced by `data` in DataTables to ensure naming
12338.
         * consistency. `dataProp` can still be used, as there is backwards
12339.
         * compatibility in DataTables for this option, but it is strongly
12340.
         * recommended that you use `data` in preference to `dataProp`.
12341.
         *  @name DataTable.defaults.column.dataProp
12342.
         */
12343.
    
12344.
    
12345.
        /**
12346.
         * This property can be used to read data from any data source property,
12347.
         * including deeply nested objects / properties. `data` can be given in a
12348.
         * number of different ways which effect its behaviour:
12349.
         *
12350.
         * * `integer` - treated as an array index for the data source. This is the
12351.
         *   default that DataTables uses (incrementally increased for each column).
12352.
         * * `string` - read an object property from the data source. There are
12353.
         *   three 'special' options that can be used in the string to alter how
12354.
         *   DataTables reads the data from the source object:
12355.
         *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12356.
         *      Javascript to read from nested objects, so to can the options
12357.
         *      specified in `data`. For example: `browser.version` or
12358.
         *      `browser.name`. If your object parameter name contains a period, use
12359.
         *      `\\` to escape it - i.e. `first\\.name`.
12360.
         *    * `[]` - Array notation. DataTables can automatically combine data
12361.
         *      from and array source, joining the data with the characters provided
12362.
         *      between the two brackets. For example: `name[, ]` would provide a
12363.
         *      comma-space separated list from the source array. If no characters
12364.
         *      are provided between the brackets, the original array source is
12365.
         *      returned.
12366.
         *    * `()` - Function notation. Adding `()` to the end of a parameter will
12367.
         *      execute a function of the name given. For example: `browser()` for a
12368.
         *      simple function on the data source, `browser.version()` for a
12369.
         *      function in a nested property or even `browser().version` to get an
12370.
         *      object property if the function called returns an object. Note that
12371.
         *      function notation is recommended for use in `render` rather than
12372.
         *      `data` as it is much simpler to use as a renderer.
12373.
         * * `null` - use the original data source for the row rather than plucking
12374.
         *   data directly from it. This action has effects on two other
12375.
         *   initialisation options:
12376.
         *    * `defaultContent` - When null is given as the `data` option and
12377.
         *      `defaultContent` is specified for the column, the value defined by
12378.
         *      `defaultContent` will be used for the cell.
12379.
         *    * `render` - When null is used for the `data` option and the `render`
12380.
         *      option is specified for the column, the whole data source for the
12381.
         *      row is used for the renderer.
12382.
         * * `function` - the function given will be executed whenever DataTables
12383.
         *   needs to set or get the data for a cell in the column. The function
12384.
         *   takes three parameters:
12385.
         *    * Parameters:
12386.
         *      * `{array|object}` The data source for the row
12387.
         *      * `{string}` The type call data requested - this will be 'set' when
12388.
         *        setting data or 'filter', 'display', 'type', 'sort' or undefined
12389.
         *        when gathering data. Note that when `undefined` is given for the
12390.
         *        type DataTables expects to get the raw data for the object back<
12391.
         *      * `{*}` Data to set when the second parameter is 'set'.
12392.
         *    * Return:
12393.
         *      * The return value from the function is not required when 'set' is
12394.
         *        the type of call, but otherwise the return is what will be used
12395.
         *        for the data requested.
12396.
         *
12397.
         * Note that `data` is a getter and setter option. If you just require
12398.
         * formatting of data for output, you will likely want to use `render` which
12399.
         * is simply a getter and thus simpler to use.
12400.
         *
12401.
         * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12402.
         * name change reflects the flexibility of this property and is consistent
12403.
         * with the naming of mRender. If 'mDataProp' is given, then it will still
12404.
         * be used by DataTables, as it automatically maps the old name to the new
12405.
         * if required.
12406.
         *
12407.
         *  @type string|int|function|null
12408.
         *  @default null <i>Use automatically calculated column index</i>
12409.
         *
12410.
         *  @name DataTable.defaults.column.data
12411.
         *  @dtopt Columns
12412.
         *
12413.
         *  @example
12414.
         *    // Read table data from objects
12415.
         *    // JSON structure for each row:
12416.
         *    //   {
12417.
         *    //      "engine": {value},
12418.
         *    //      "browser": {value},
12419.
         *    //      "platform": {value},
12420.
         *    //      "version": {value},
12421.
         *    //      "grade": {value}
12422.
         *    //   }
12423.
         *    $(document).ready( function() {
12424.
         *      $('#example').dataTable( {
12425.
         *        "ajaxSource": "sources/objects.txt",
12426.
         *        "columns": [
12427.
         *          { "data": "engine" },
12428.
         *          { "data": "browser" },
12429.
         *          { "data": "platform" },
12430.
         *          { "data": "version" },
12431.
         *          { "data": "grade" }
12432.
         *        ]
12433.
         *      } );
12434.
         *    } );
12435.
         *
12436.
         *  @example
12437.
         *    // Read information from deeply nested objects
12438.
         *    // JSON structure for each row:
12439.
         *    //   {
12440.
         *    //      "engine": {value},
12441.
         *    //      "browser": {value},
12442.
         *    //      "platform": {
12443.
         *    //         "inner": {value}
12444.
         *    //      },
12445.
         *    //      "details": [
12446.
         *    //         {value}, {value}
12447.
         *    //      ]
12448.
         *    //   }
12449.
         *    $(document).ready( function() {
12450.
         *      $('#example').dataTable( {
12451.
         *        "ajaxSource": "sources/deep.txt",
12452.
         *        "columns": [
12453.
         *          { "data": "engine" },
12454.
         *          { "data": "browser" },
12455.
         *          { "data": "platform.inner" },
12456.
         *          { "data": "details.0" },
12457.
         *          { "data": "details.1" }
12458.
         *        ]
12459.
         *      } );
12460.
         *    } );
12461.
         *
12462.
         *  @example
12463.
         *    // Using `data` as a function to provide different information for
12464.
         *    // sorting, filtering and display. In this case, currency (price)
12465.
         *    $(document).ready( function() {
12466.
         *      $('#example').dataTable( {
12467.
         *        "columnDefs": [ {
12468.
         *          "targets": [ 0 ],
12469.
         *          "data": function ( source, type, val ) {
12470.
         *            if (type === 'set') {
12471.
         *              source.price = val;
12472.
         *              // Store the computed dislay and filter values for efficiency
12473.
         *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
12474.
         *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12475.
         *              return;
12476.
         *            }
12477.
         *            else if (type === 'display') {
12478.
         *              return source.price_display;
12479.
         *            }
12480.
         *            else if (type === 'filter') {
12481.
         *              return source.price_filter;
12482.
         *            }
12483.
         *            // 'sort', 'type' and undefined all just use the integer
12484.
         *            return source.price;
12485.
         *          }
12486.
         *        } ]
12487.
         *      } );
12488.
         *    } );
12489.
         *
12490.
         *  @example
12491.
         *    // Using default content
12492.
         *    $(document).ready( function() {
12493.
         *      $('#example').dataTable( {
12494.
         *        "columnDefs": [ {
12495.
         *          "targets": [ 0 ],
12496.
         *          "data": null,
12497.
         *          "defaultContent": "Click to edit"
12498.
         *        } ]
12499.
         *      } );
12500.
         *    } );
12501.
         *
12502.
         *  @example
12503.
         *    // Using array notation - outputting a list from an array
12504.
         *    $(document).ready( function() {
12505.
         *      $('#example').dataTable( {
12506.
         *        "columnDefs": [ {
12507.
         *          "targets": [ 0 ],
12508.
         *          "data": "name[, ]"
12509.
         *        } ]
12510.
         *      } );
12511.
         *    } );
12512.
         *
12513.
         */
12514.
        "mData": null,
12515.
    
12516.
    
12517.
        /**
12518.
         * This property is the rendering partner to `data` and it is suggested that
12519.
         * when you want to manipulate data for display (including filtering,
12520.
         * sorting etc) without altering the underlying data for the table, use this
12521.
         * property. `render` can be considered to be the the read only companion to
12522.
         * `data` which is read / write (then as such more complex). Like `data`
12523.
         * this option can be given in a number of different ways to effect its
12524.
         * behaviour:
12525.
         *
12526.
         * * `integer` - treated as an array index for the data source. This is the
12527.
         *   default that DataTables uses (incrementally increased for each column).
12528.
         * * `string` - read an object property from the data source. There are
12529.
         *   three 'special' options that can be used in the string to alter how
12530.
         *   DataTables reads the data from the source object:
12531.
         *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12532.
         *      Javascript to read from nested objects, so to can the options
12533.
         *      specified in `data`. For example: `browser.version` or
12534.
         *      `browser.name`. If your object parameter name contains a period, use
12535.
         *      `\\` to escape it - i.e. `first\\.name`.
12536.
         *    * `[]` - Array notation. DataTables can automatically combine data
12537.
         *      from and array source, joining the data with the characters provided
12538.
         *      between the two brackets. For example: `name[, ]` would provide a
12539.
         *      comma-space separated list from the source array. If no characters
12540.
         *      are provided between the brackets, the original array source is
12541.
         *      returned.
12542.
         *    * `()` - Function notation. Adding `()` to the end of a parameter will
12543.
         *      execute a function of the name given. For example: `browser()` for a
12544.
         *      simple function on the data source, `browser.version()` for a
12545.
         *      function in a nested property or even `browser().version` to get an
12546.
         *      object property if the function called returns an object.
12547.
         * * `object` - use different data for the different data types requested by
12548.
         *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
12549.
         *   of the object is the data type the property refers to and the value can
12550.
         *   defined using an integer, string or function using the same rules as
12551.
         *   `render` normally does. Note that an `_` option _must_ be specified.
12552.
         *   This is the default value to use if you haven't specified a value for
12553.
         *   the data type requested by DataTables.
12554.
         * * `function` - the function given will be executed whenever DataTables
12555.
         *   needs to set or get the data for a cell in the column. The function
12556.
         *   takes three parameters:
12557.
         *    * Parameters:
12558.
         *      * {array|object} The data source for the row (based on `data`)
12559.
         *      * {string} The type call data requested - this will be 'filter',
12560.
         *        'display', 'type' or 'sort'.
12561.
         *      * {array|object} The full data source for the row (not based on
12562.
         *        `data`)
12563.
         *    * Return:
12564.
         *      * The return value from the function is what will be used for the
12565.
         *        data requested.
12566.
         *
12567.
         *  @type string|int|function|object|null
12568.
         *  @default null Use the data source value.
12569.
         *
12570.
         *  @name DataTable.defaults.column.render
12571.
         *  @dtopt Columns
12572.
         *
12573.
         *  @example
12574.
         *    // Create a comma separated list from an array of objects
12575.
         *    $(document).ready( function() {
12576.
         *      $('#example').dataTable( {
12577.
         *        "ajaxSource": "sources/deep.txt",
12578.
         *        "columns": [
12579.
         *          { "data": "engine" },
12580.
         *          { "data": "browser" },
12581.
         *          {
12582.
         *            "data": "platform",
12583.
         *            "render": "[, ].name"
12584.
         *          }
12585.
         *        ]
12586.
         *      } );
12587.
         *    } );
12588.
         *
12589.
         *  @example
12590.
         *    // Execute a function to obtain data
12591.
         *    $(document).ready( function() {
12592.
         *      $('#example').dataTable( {
12593.
         *        "columnDefs": [ {
12594.
         *          "targets": [ 0 ],
12595.
         *          "data": null, // Use the full data source object for the renderer's source
12596.
         *          "render": "browserName()"
12597.
         *        } ]
12598.
         *      } );
12599.
         *    } );
12600.
         *
12601.
         *  @example
12602.
         *    // As an object, extracting different data for the different types
12603.
         *    // This would be used with a data source such as:
12604.
         *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12605.
         *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12606.
         *    // (which has both forms) is used for filtering for if a user inputs either format, while
12607.
         *    // the formatted phone number is the one that is shown in the table.
12608.
         *    $(document).ready( function() {
12609.
         *      $('#example').dataTable( {
12610.
         *        "columnDefs": [ {
12611.
         *          "targets": [ 0 ],
12612.
         *          "data": null, // Use the full data source object for the renderer's source
12613.
         *          "render": {
12614.
         *            "_": "phone",
12615.
         *            "filter": "phone_filter",
12616.
         *            "display": "phone_display"
12617.
         *          }
12618.
         *        } ]
12619.
         *      } );
12620.
         *    } );
12621.
         *
12622.
         *  @example
12623.
         *    // Use as a function to create a link from the data source
12624.
         *    $(document).ready( function() {
12625.
         *      $('#example').dataTable( {
12626.
         *        "columnDefs": [ {
12627.
         *          "targets": [ 0 ],
12628.
         *          "data": "download_link",
12629.
         *          "render": function ( data, type, full ) {
12630.
         *            return '<a href="'+data+'">Download</a>';
12631.
         *          }
12632.
         *        } ]
12633.
         *      } );
12634.
         *    } );
12635.
         */
12636.
        "mRender": null,
12637.
    
12638.
    
12639.
        /**
12640.
         * Change the cell type created for the column - either TD cells or TH cells. This
12641.
         * can be useful as TH cells have semantic meaning in the table body, allowing them
12642.
         * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12643.
         *  @type string
12644.
         *  @default td
12645.
         *
12646.
         *  @name DataTable.defaults.column.cellType
12647.
         *  @dtopt Columns
12648.
         *
12649.
         *  @example
12650.
         *    // Make the first column use TH cells
12651.
         *    $(document).ready( function() {
12652.
         *      $('#example').dataTable( {
12653.
         *        "columnDefs": [ {
12654.
         *          "targets": [ 0 ],
12655.
         *          "cellType": "th"
12656.
         *        } ]
12657.
         *      } );
12658.
         *    } );
12659.
         */
12660.
        "sCellType": "td",
12661.
    
12662.
    
12663.
        /**
12664.
         * Class to give to each cell in this column.
12665.
         *  @type string
12666.
         *  @default <i>Empty string</i>
12667.
         *
12668.
         *  @name DataTable.defaults.column.class
12669.
         *  @dtopt Columns
12670.
         *
12671.
         *  @example
12672.
         *    // Using `columnDefs`
12673.
         *    $(document).ready( function() {
12674.
         *      $('#example').dataTable( {
12675.
         *        "columnDefs": [
12676.
         *          { "class": "my_class", "targets": [ 0 ] }
12677.
         *        ]
12678.
         *      } );
12679.
         *    } );
12680.
         *
12681.
         *  @example
12682.
         *    // Using `columns`
12683.
         *    $(document).ready( function() {
12684.
         *      $('#example').dataTable( {
12685.
         *        "columns": [
12686.
         *          { "class": "my_class" },
12687.
         *          null,
12688.
         *          null,
12689.
         *          null,
12690.
         *          null
12691.
         *        ]
12692.
         *      } );
12693.
         *    } );
12694.
         */
12695.
        "sClass": "",
12696.
    
12697.
        /**
12698.
         * When DataTables calculates the column widths to assign to each column,
12699.
         * it finds the longest string in each column and then constructs a
12700.
         * temporary table and reads the widths from that. The problem with this
12701.
         * is that "mmm" is much wider then "iiii", but the latter is a longer
12702.
         * string - thus the calculation can go wrong (doing it properly and putting
12703.
         * it into an DOM object and measuring that is horribly(!) slow). Thus as
12704.
         * a "work around" we provide this option. It will append its value to the
12705.
         * text that is found to be the longest string for the column - i.e. padding.
12706.
         * Generally you shouldn't need this!
12707.
         *  @type string
12708.
         *  @default <i>Empty string<i>
12709.
         *
12710.
         *  @name DataTable.defaults.column.contentPadding
12711.
         *  @dtopt Columns
12712.
         *
12713.
         *  @example
12714.
         *    // Using `columns`
12715.
         *    $(document).ready( function() {
12716.
         *      $('#example').dataTable( {
12717.
         *        "columns": [
12718.
         *          null,
12719.
         *          null,
12720.
         *          null,
12721.
         *          {
12722.
         *            "contentPadding": "mmm"
12723.
         *          }
12724.
         *        ]
12725.
         *      } );
12726.
         *    } );
12727.
         */
12728.
        "sContentPadding": "",
12729.
    
12730.
    
12731.
        /**
12732.
         * Allows a default value to be given for a column's data, and will be used
12733.
         * whenever a null data source is encountered (this can be because `data`
12734.
         * is set to null, or because the data source itself is null).
12735.
         *  @type string
12736.
         *  @default null
12737.
         *
12738.
         *  @name DataTable.defaults.column.defaultContent
12739.
         *  @dtopt Columns
12740.
         *
12741.
         *  @example
12742.
         *    // Using `columnDefs`
12743.
         *    $(document).ready( function() {
12744.
         *      $('#example').dataTable( {
12745.
         *        "columnDefs": [
12746.
         *          {
12747.
         *            "data": null,
12748.
         *            "defaultContent": "Edit",
12749.
         *            "targets": [ -1 ]
12750.
         *          }
12751.
         *        ]
12752.
         *      } );
12753.
         *    } );
12754.
         *
12755.
         *  @example
12756.
         *    // Using `columns`
12757.
         *    $(document).ready( function() {
12758.
         *      $('#example').dataTable( {
12759.
         *        "columns": [
12760.
         *          null,
12761.
         *          null,
12762.
         *          null,
12763.
         *          {
12764.
         *            "data": null,
12765.
         *            "defaultContent": "Edit"
12766.
         *          }
12767.
         *        ]
12768.
         *      } );
12769.
         *    } );
12770.
         */
12771.
        "sDefaultContent": null,
12772.
    
12773.
    
12774.
        /**
12775.
         * This parameter is only used in DataTables' server-side processing. It can
12776.
         * be exceptionally useful to know what columns are being displayed on the
12777.
         * client side, and to map these to database fields. When defined, the names
12778.
         * also allow DataTables to reorder information from the server if it comes
12779.
         * back in an unexpected order (i.e. if you switch your columns around on the
12780.
         * client-side, your server-side code does not also need updating).
12781.
         *  @type string
12782.
         *  @default <i>Empty string</i>
12783.
         *
12784.
         *  @name DataTable.defaults.column.name
12785.
         *  @dtopt Columns
12786.
         *
12787.
         *  @example
12788.
         *    // Using `columnDefs`
12789.
         *    $(document).ready( function() {
12790.
         *      $('#example').dataTable( {
12791.
         *        "columnDefs": [
12792.
         *          { "name": "engine", "targets": [ 0 ] },
12793.
         *          { "name": "browser", "targets": [ 1 ] },
12794.
         *          { "name": "platform", "targets": [ 2 ] },
12795.
         *          { "name": "version", "targets": [ 3 ] },
12796.
         *          { "name": "grade", "targets": [ 4 ] }
12797.
         *        ]
12798.
         *      } );
12799.
         *    } );
12800.
         *
12801.
         *  @example
12802.
         *    // Using `columns`
12803.
         *    $(document).ready( function() {
12804.
         *      $('#example').dataTable( {
12805.
         *        "columns": [
12806.
         *          { "name": "engine" },
12807.
         *          { "name": "browser" },
12808.
         *          { "name": "platform" },
12809.
         *          { "name": "version" },
12810.
         *          { "name": "grade" }
12811.
         *        ]
12812.
         *      } );
12813.
         *    } );
12814.
         */
12815.
        "sName": "",
12816.
    
12817.
    
12818.
        /**
12819.
         * Defines a data source type for the ordering which can be used to read
12820.
         * real-time information from the table (updating the internally cached
12821.
         * version) prior to ordering. This allows ordering to occur on user
12822.
         * editable elements such as form inputs.
12823.
         *  @type string
12824.
         *  @default std
12825.
         *
12826.
         *  @name DataTable.defaults.column.orderDataType
12827.
         *  @dtopt Columns
12828.
         *
12829.
         *  @example
12830.
         *    // Using `columnDefs`
12831.
         *    $(document).ready( function() {
12832.
         *      $('#example').dataTable( {
12833.
         *        "columnDefs": [
12834.
         *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12835.
         *          { "type": "numeric", "targets": [ 3 ] },
12836.
         *          { "orderDataType": "dom-select", "targets": [ 4 ] },
12837.
         *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12838.
         *        ]
12839.
         *      } );
12840.
         *    } );
12841.
         *
12842.
         *  @example
12843.
         *    // Using `columns`
12844.
         *    $(document).ready( function() {
12845.
         *      $('#example').dataTable( {
12846.
         *        "columns": [
12847.
         *          null,
12848.
         *          null,
12849.
         *          { "orderDataType": "dom-text" },
12850.
         *          { "orderDataType": "dom-text", "type": "numeric" },
12851.
         *          { "orderDataType": "dom-select" },
12852.
         *          { "orderDataType": "dom-checkbox" }
12853.
         *        ]
12854.
         *      } );
12855.
         *    } );
12856.
         */
12857.
        "sSortDataType": "std",
12858.
    
12859.
    
12860.
        /**
12861.
         * The title of this column.
12862.
         *  @type string
12863.
         *  @default null <i>Derived from the 'TH' value for this column in the
12864.
         *    original HTML table.</i>
12865.
         *
12866.
         *  @name DataTable.defaults.column.title
12867.
         *  @dtopt Columns
12868.
         *
12869.
         *  @example
12870.
         *    // Using `columnDefs`
12871.
         *    $(document).ready( function() {
12872.
         *      $('#example').dataTable( {
12873.
         *        "columnDefs": [
12874.
         *          { "title": "My column title", "targets": [ 0 ] }
12875.
         *        ]
12876.
         *      } );
12877.
         *    } );
12878.
         *
12879.
         *  @example
12880.
         *    // Using `columns`
12881.
         *    $(document).ready( function() {
12882.
         *      $('#example').dataTable( {
12883.
         *        "columns": [
12884.
         *          { "title": "My column title" },
12885.
         *          null,
12886.
         *          null,
12887.
         *          null,
12888.
         *          null
12889.
         *        ]
12890.
         *      } );
12891.
         *    } );
12892.
         */
12893.
        "sTitle": null,
12894.
    
12895.
    
12896.
        /**
12897.
         * The type allows you to specify how the data for this column will be
12898.
         * ordered. Four types (string, numeric, date and html (which will strip
12899.
         * HTML tags before ordering)) are currently available. Note that only date
12900.
         * formats understood by Javascript's Date() object will be accepted as type
12901.
         * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12902.
         * 'numeric', 'date' or 'html' (by default). Further types can be adding
12903.
         * through plug-ins.
12904.
         *  @type string
12905.
         *  @default null <i>Auto-detected from raw data</i>
12906.
         *
12907.
         *  @name DataTable.defaults.column.type
12908.
         *  @dtopt Columns
12909.
         *
12910.
         *  @example
12911.
         *    // Using `columnDefs`
12912.
         *    $(document).ready( function() {
12913.
         *      $('#example').dataTable( {
12914.
         *        "columnDefs": [
12915.
         *          { "type": "html", "targets": [ 0 ] }
12916.
         *        ]
12917.
         *      } );
12918.
         *    } );
12919.
         *
12920.
         *  @example
12921.
         *    // Using `columns`
12922.
         *    $(document).ready( function() {
12923.
         *      $('#example').dataTable( {
12924.
         *        "columns": [
12925.
         *          { "type": "html" },
12926.
         *          null,
12927.
         *          null,
12928.
         *          null,
12929.
         *          null
12930.
         *        ]
12931.
         *      } );
12932.
         *    } );
12933.
         */
12934.
        "sType": null,
12935.
    
12936.
    
12937.
        /**
12938.
         * Defining the width of the column, this parameter may take any CSS value
12939.
         * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12940.
         * been given a specific width through this interface ensuring that the table
12941.
         * remains readable.
12942.
         *  @type string
12943.
         *  @default null <i>Automatic</i>
12944.
         *
12945.
         *  @name DataTable.defaults.column.width
12946.
         *  @dtopt Columns
12947.
         *
12948.
         *  @example
12949.
         *    // Using `columnDefs`
12950.
         *    $(document).ready( function() {
12951.
         *      $('#example').dataTable( {
12952.
         *        "columnDefs": [
12953.
         *          { "width": "20%", "targets": [ 0 ] }
12954.
         *        ]
12955.
         *      } );
12956.
         *    } );
12957.
         *
12958.
         *  @example
12959.
         *    // Using `columns`
12960.
         *    $(document).ready( function() {
12961.
         *      $('#example').dataTable( {
12962.
         *        "columns": [
12963.
         *          { "width": "20%" },
12964.
         *          null,
12965.
         *          null,
12966.
         *          null,
12967.
         *          null
12968.
         *        ]
12969.
         *      } );
12970.
         *    } );
12971.
         */
12972.
        "sWidth": null
12973.
    };
12974.
    
12975.
    _fnHungarianMap( DataTable.defaults.column );
12976.
    
12977.
    
12978.
    
12979.
    /**
12980.
     * DataTables settings object - this holds all the information needed for a
12981.
     * given table, including configuration, data and current application of the
12982.
     * table options. DataTables does not have a single instance for each DataTable
12983.
     * with the settings attached to that instance, but rather instances of the
12984.
     * DataTable "class" are created on-the-fly as needed (typically by a
12985.
     * $().dataTable() call) and the settings object is then applied to that
12986.
     * instance.
12987.
     *
12988.
     * Note that this object is related to {@link DataTable.defaults} but this
12989.
     * one is the internal data store for DataTables's cache of columns. It should
12990.
     * NOT be manipulated outside of DataTables. Any configuration should be done
12991.
     * through the initialisation options.
12992.
     *  @namespace
12993.
     *  @todo Really should attach the settings object to individual instances so we
12994.
     *    don't need to create new instances on each $().dataTable() call (if the
12995.
     *    table already exists). It would also save passing oSettings around and
12996.
     *    into every single function. However, this is a very significant
12997.
     *    architecture change for DataTables and will almost certainly break
12998.
     *    backwards compatibility with older installations. This is something that
12999.
     *    will be done in 2.0.
13000.
     */
13001.
    DataTable.models.oSettings = {
13002.
        /**
13003.
         * Primary features of DataTables and their enablement state.
13004.
         *  @namespace
13005.
         */
13006.
        "oFeatures": {
13007.
    
13008.
            /**
13009.
             * Flag to say if DataTables should automatically try to calculate the
13010.
             * optimum table and columns widths (true) or not (false).
13011.
             * Note that this parameter will be set by the initialisation routine. To
13012.
             * set a default use {@link DataTable.defaults}.
13013.
             *  @type boolean
13014.
             */
13015.
            "bAutoWidth": null,
13016.
    
13017.
            /**
13018.
             * Delay the creation of TR and TD elements until they are actually
13019.
             * needed by a driven page draw. This can give a significant speed
13020.
             * increase for Ajax source and Javascript source data, but makes no
13021.
             * difference at all fro DOM and server-side processing tables.
13022.
             * Note that this parameter will be set by the initialisation routine. To
13023.
             * set a default use {@link DataTable.defaults}.
13024.
             *  @type boolean
13025.
             */
13026.
            "bDeferRender": null,
13027.
    
13028.
            /**
13029.
             * Enable filtering on the table or not. Note that if this is disabled
13030.
             * then there is no filtering at all on the table, including fnFilter.
13031.
             * To just remove the filtering input use sDom and remove the 'f' option.
13032.
             * Note that this parameter will be set by the initialisation routine. To
13033.
             * set a default use {@link DataTable.defaults}.
13034.
             *  @type boolean
13035.
             */
13036.
            "bFilter": null,
13037.
    
13038.
            /**
13039.
             * Table information element (the 'Showing x of y records' div) enable
13040.
             * flag.
13041.
             * Note that this parameter will be set by the initialisation routine. To
13042.
             * set a default use {@link DataTable.defaults}.
13043.
             *  @type boolean
13044.
             */
13045.
            "bInfo": null,
13046.
    
13047.
            /**
13048.
             * Present a user control allowing the end user to change the page size
13049.
             * when pagination is enabled.
13050.
             * Note that this parameter will be set by the initialisation routine. To
13051.
             * set a default use {@link DataTable.defaults}.
13052.
             *  @type boolean
13053.
             */
13054.
            "bLengthChange": null,
13055.
    
13056.
            /**
13057.
             * Pagination enabled or not. Note that if this is disabled then length
13058.
             * changing must also be disabled.
13059.
             * Note that this parameter will be set by the initialisation routine. To
13060.
             * set a default use {@link DataTable.defaults}.
13061.
             *  @type boolean
13062.
             */
13063.
            "bPaginate": null,
13064.
    
13065.
            /**
13066.
             * Processing indicator enable flag whenever DataTables is enacting a
13067.
             * user request - typically an Ajax request for server-side processing.
13068.
             * Note that this parameter will be set by the initialisation routine. To
13069.
             * set a default use {@link DataTable.defaults}.
13070.
             *  @type boolean
13071.
             */
13072.
            "bProcessing": null,
13073.
    
13074.
            /**
13075.
             * Server-side processing enabled flag - when enabled DataTables will
13076.
             * get all data from the server for every draw - there is no filtering,
13077.
             * sorting or paging done on the client-side.
13078.
             * Note that this parameter will be set by the initialisation routine. To
13079.
             * set a default use {@link DataTable.defaults}.
13080.
             *  @type boolean
13081.
             */
13082.
            "bServerSide": null,
13083.
    
13084.
            /**
13085.
             * Sorting enablement flag.
13086.
             * Note that this parameter will be set by the initialisation routine. To
13087.
             * set a default use {@link DataTable.defaults}.
13088.
             *  @type boolean
13089.
             */
13090.
            "bSort": null,
13091.
    
13092.
            /**
13093.
             * Multi-column sorting
13094.
             * Note that this parameter will be set by the initialisation routine. To
13095.
             * set a default use {@link DataTable.defaults}.
13096.
             *  @type boolean
13097.
             */
13098.
            "bSortMulti": null,
13099.
    
13100.
            /**
13101.
             * Apply a class to the columns which are being sorted to provide a
13102.
             * visual highlight or not. This can slow things down when enabled since
13103.
             * there is a lot of DOM interaction.
13104.
             * Note that this parameter will be set by the initialisation routine. To
13105.
             * set a default use {@link DataTable.defaults}.
13106.
             *  @type boolean
13107.
             */
13108.
            "bSortClasses": null,
13109.
    
13110.
            /**
13111.
             * State saving enablement flag.
13112.
             * Note that this parameter will be set by the initialisation routine. To
13113.
             * set a default use {@link DataTable.defaults}.
13114.
             *  @type boolean
13115.
             */
13116.
            "bStateSave": null
13117.
        },
13118.
    
13119.
    
13120.
        /**
13121.
         * Scrolling settings for a table.
13122.
         *  @namespace
13123.
         */
13124.
        "oScroll": {
13125.
            /**
13126.
             * When the table is shorter in height than sScrollY, collapse the
13127.
             * table container down to the height of the table (when true).
13128.
             * Note that this parameter will be set by the initialisation routine. To
13129.
             * set a default use {@link DataTable.defaults}.
13130.
             *  @type boolean
13131.
             */
13132.
            "bCollapse": null,
13133.
    
13134.
            /**
13135.
             * Width of the scrollbar for the web-browser's platform. Calculated
13136.
             * during table initialisation.
13137.
             *  @type int
13138.
             *  @default 0
13139.
             */
13140.
            "iBarWidth": 0,
13141.
    
13142.
            /**
13143.
             * Viewport width for horizontal scrolling. Horizontal scrolling is
13144.
             * disabled if an empty string.
13145.
             * Note that this parameter will be set by the initialisation routine. To
13146.
             * set a default use {@link DataTable.defaults}.
13147.
             *  @type string
13148.
             */
13149.
            "sX": null,
13150.
    
13151.
            /**
13152.
             * Width to expand the table to when using x-scrolling. Typically you
13153.
             * should not need to use this.
13154.
             * Note that this parameter will be set by the initialisation routine. To
13155.
             * set a default use {@link DataTable.defaults}.
13156.
             *  @type string
13157.
             *  @deprecated
13158.
             */
13159.
            "sXInner": null,
13160.
    
13161.
            /**
13162.
             * Viewport height for vertical scrolling. Vertical scrolling is disabled
13163.
             * if an empty string.
13164.
             * Note that this parameter will be set by the initialisation routine. To
13165.
             * set a default use {@link DataTable.defaults}.
13166.
             *  @type string
13167.
             */
13168.
            "sY": null
13169.
        },
13170.
    
13171.
        /**
13172.
         * Language information for the table.
13173.
         *  @namespace
13174.
         *  @extends DataTable.defaults.oLanguage
13175.
         */
13176.
        "oLanguage": {
13177.
            /**
13178.
             * Information callback function. See
13179.
             * {@link DataTable.defaults.fnInfoCallback}
13180.
             *  @type function
13181.
             *  @default null
13182.
             */
13183.
            "fnInfoCallback": null
13184.
        },
13185.
    
13186.
        /**
13187.
         * Browser support parameters
13188.
         *  @namespace
13189.
         */
13190.
        "oBrowser": {
13191.
            /**
13192.
             * Indicate if the browser incorrectly calculates width:100% inside a
13193.
             * scrolling element (IE6/7)
13194.
             *  @type boolean
13195.
             *  @default false
13196.
             */
13197.
            "bScrollOversize": false,
13198.
    
13199.
            /**
13200.
             * Determine if the vertical scrollbar is on the right or left of the
13201.
             * scrolling container - needed for rtl language layout, although not
13202.
             * all browsers move the scrollbar (Safari).
13203.
             *  @type boolean
13204.
             *  @default false
13205.
             */
13206.
            "bScrollbarLeft": false,
13207.
    
13208.
            /**
13209.
             * Flag for if `getBoundingClientRect` is fully supported or not
13210.
             *  @type boolean
13211.
             *  @default false
13212.
             */
13213.
            "bBounding": false,
13214.
    
13215.
            /**
13216.
             * Browser scrollbar width
13217.
             *  @type integer
13218.
             *  @default 0
13219.
             */
13220.
            "barWidth": 0
13221.
        },
13222.
    
13223.
    
13224.
        "ajax": null,
13225.
    
13226.
    
13227.
        /**
13228.
         * Array referencing the nodes which are used for the features. The
13229.
         * parameters of this object match what is allowed by sDom - i.e.
13230.
         *   <ul>
13231.
         *     <li>'l' - Length changing</li>
13232.
         *     <li>'f' - Filtering input</li>
13233.
         *     <li>'t' - The table!</li>
13234.
         *     <li>'i' - Information</li>
13235.
         *     <li>'p' - Pagination</li>
13236.
         *     <li>'r' - pRocessing</li>
13237.
         *   </ul>
13238.
         *  @type array
13239.
         *  @default []
13240.
         */
13241.
        "aanFeatures": [],
13242.
    
13243.
        /**
13244.
         * Store data information - see {@link DataTable.models.oRow} for detailed
13245.
         * information.
13246.
         *  @type array
13247.
         *  @default []
13248.
         */
13249.
        "aoData": [],
13250.
    
13251.
        /**
13252.
         * Array of indexes which are in the current display (after filtering etc)
13253.
         *  @type array
13254.
         *  @default []
13255.
         */
13256.
        "aiDisplay": [],
13257.
    
13258.
        /**
13259.
         * Array of indexes for display - no filtering
13260.
         *  @type array
13261.
         *  @default []
13262.
         */
13263.
        "aiDisplayMaster": [],
13264.
    
13265.
        /**
13266.
         * Map of row ids to data indexes
13267.
         *  @type object
13268.
         *  @default {}
13269.
         */
13270.
        "aIds": {},
13271.
    
13272.
        /**
13273.
         * Store information about each column that is in use
13274.
         *  @type array
13275.
         *  @default []
13276.
         */
13277.
        "aoColumns": [],
13278.
    
13279.
        /**
13280.
         * Store information about the table's header
13281.
         *  @type array
13282.
         *  @default []
13283.
         */
13284.
        "aoHeader": [],
13285.
    
13286.
        /**
13287.
         * Store information about the table's footer
13288.
         *  @type array
13289.
         *  @default []
13290.
         */
13291.
        "aoFooter": [],
13292.
    
13293.
        /**
13294.
         * Store the applied global search information in case we want to force a
13295.
         * research or compare the old search to a new one.
13296.
         * Note that this parameter will be set by the initialisation routine. To
13297.
         * set a default use {@link DataTable.defaults}.
13298.
         *  @namespace
13299.
         *  @extends DataTable.models.oSearch
13300.
         */
13301.
        "oPreviousSearch": {},
13302.
    
13303.
        /**
13304.
         * Store the applied search for each column - see
13305.
         * {@link DataTable.models.oSearch} for the format that is used for the
13306.
         * filtering information for each column.
13307.
         *  @type array
13308.
         *  @default []
13309.
         */
13310.
        "aoPreSearchCols": [],
13311.
    
13312.
        /**
13313.
         * Sorting that is applied to the table. Note that the inner arrays are
13314.
         * used in the following manner:
13315.
         * <ul>
13316.
         *   <li>Index 0 - column number</li>
13317.
         *   <li>Index 1 - current sorting direction</li>
13318.
         * </ul>
13319.
         * Note that this parameter will be set by the initialisation routine. To
13320.
         * set a default use {@link DataTable.defaults}.
13321.
         *  @type array
13322.
         *  @todo These inner arrays should really be objects
13323.
         */
13324.
        "aaSorting": null,
13325.
    
13326.
        /**
13327.
         * Sorting that is always applied to the table (i.e. prefixed in front of
13328.
         * aaSorting).
13329.
         * Note that this parameter will be set by the initialisation routine. To
13330.
         * set a default use {@link DataTable.defaults}.
13331.
         *  @type array
13332.
         *  @default []
13333.
         */
13334.
        "aaSortingFixed": [],
13335.
    
13336.
        /**
13337.
         * Classes to use for the striping of a table.
13338.
         * Note that this parameter will be set by the initialisation routine. To
13339.
         * set a default use {@link DataTable.defaults}.
13340.
         *  @type array
13341.
         *  @default []
13342.
         */
13343.
        "asStripeClasses": null,
13344.
    
13345.
        /**
13346.
         * If restoring a table - we should restore its striping classes as well
13347.
         *  @type array
13348.
         *  @default []
13349.
         */
13350.
        "asDestroyStripes": [],
13351.
    
13352.
        /**
13353.
         * If restoring a table - we should restore its width
13354.
         *  @type int
13355.
         *  @default 0
13356.
         */
13357.
        "sDestroyWidth": 0,
13358.
    
13359.
        /**
13360.
         * Callback functions array for every time a row is inserted (i.e. on a draw).
13361.
         *  @type array
13362.
         *  @default []
13363.
         */
13364.
        "aoRowCallback": [],
13365.
    
13366.
        /**
13367.
         * Callback functions for the header on each draw.
13368.
         *  @type array
13369.
         *  @default []
13370.
         */
13371.
        "aoHeaderCallback": [],
13372.
    
13373.
        /**
13374.
         * Callback function for the footer on each draw.
13375.
         *  @type array
13376.
         *  @default []
13377.
         */
13378.
        "aoFooterCallback": [],
13379.
    
13380.
        /**
13381.
         * Array of callback functions for draw callback functions
13382.
         *  @type array
13383.
         *  @default []
13384.
         */
13385.
        "aoDrawCallback": [],
13386.
    
13387.
        /**
13388.
         * Array of callback functions for row created function
13389.
         *  @type array
13390.
         *  @default []
13391.
         */
13392.
        "aoRowCreatedCallback": [],
13393.
    
13394.
        /**
13395.
         * Callback functions for just before the table is redrawn. A return of
13396.
         * false will be used to cancel the draw.
13397.
         *  @type array
13398.
         *  @default []
13399.
         */
13400.
        "aoPreDrawCallback": [],
13401.
    
13402.
        /**
13403.
         * Callback functions for when the table has been initialised.
13404.
         *  @type array
13405.
         *  @default []
13406.
         */
13407.
        "aoInitComplete": [],
13408.
    
13409.
    
13410.
        /**
13411.
         * Callbacks for modifying the settings to be stored for state saving, prior to
13412.
         * saving state.
13413.
         *  @type array
13414.
         *  @default []
13415.
         */
13416.
        "aoStateSaveParams": [],
13417.
    
13418.
        /**
13419.
         * Callbacks for modifying the settings that have been stored for state saving
13420.
         * prior to using the stored values to restore the state.
13421.
         *  @type array
13422.
         *  @default []
13423.
         */
13424.
        "aoStateLoadParams": [],
13425.
    
13426.
        /**
13427.
         * Callbacks for operating on the settings object once the saved state has been
13428.
         * loaded
13429.
         *  @type array
13430.
         *  @default []
13431.
         */
13432.
        "aoStateLoaded": [],
13433.
    
13434.
        /**
13435.
         * Cache the table ID for quick access
13436.
         *  @type string
13437.
         *  @default <i>Empty string</i>
13438.
         */
13439.
        "sTableId": "",
13440.
    
13441.
        /**
13442.
         * The TABLE node for the main table
13443.
         *  @type node
13444.
         *  @default null
13445.
         */
13446.
        "nTable": null,
13447.
    
13448.
        /**
13449.
         * Permanent ref to the thead element
13450.
         *  @type node
13451.
         *  @default null
13452.
         */
13453.
        "nTHead": null,
13454.
    
13455.
        /**
13456.
         * Permanent ref to the tfoot element - if it exists
13457.
         *  @type node
13458.
         *  @default null
13459.
         */
13460.
        "nTFoot": null,
13461.
    
13462.
        /**
13463.
         * Permanent ref to the tbody element
13464.
         *  @type node
13465.
         *  @default null
13466.
         */
13467.
        "nTBody": null,
13468.
    
13469.
        /**
13470.
         * Cache the wrapper node (contains all DataTables controlled elements)
13471.
         *  @type node
13472.
         *  @default null
13473.
         */
13474.
        "nTableWrapper": null,
13475.
    
13476.
        /**
13477.
         * Indicate if when using server-side processing the loading of data
13478.
         * should be deferred until the second draw.
13479.
         * Note that this parameter will be set by the initialisation routine. To
13480.
         * set a default use {@link DataTable.defaults}.
13481.
         *  @type boolean
13482.
         *  @default false
13483.
         */
13484.
        "bDeferLoading": false,
13485.
    
13486.
        /**
13487.
         * Indicate if all required information has been read in
13488.
         *  @type boolean
13489.
         *  @default false
13490.
         */
13491.
        "bInitialised": false,
13492.
    
13493.
        /**
13494.
         * Information about open rows. Each object in the array has the parameters
13495.
         * 'nTr' and 'nParent'
13496.
         *  @type array
13497.
         *  @default []
13498.
         */
13499.
        "aoOpenRows": [],
13500.
    
13501.
        /**
13502.
         * Dictate the positioning of DataTables' control elements - see
13503.
         * {@link DataTable.model.oInit.sDom}.
13504.
         * Note that this parameter will be set by the initialisation routine. To
13505.
         * set a default use {@link DataTable.defaults}.
13506.
         *  @type string
13507.
         *  @default null
13508.
         */
13509.
        "sDom": null,
13510.
    
13511.
        /**
13512.
         * Search delay (in mS)
13513.
         *  @type integer
13514.
         *  @default null
13515.
         */
13516.
        "searchDelay": null,
13517.
    
13518.
        /**
13519.
         * Which type of pagination should be used.
13520.
         * Note that this parameter will be set by the initialisation routine. To
13521.
         * set a default use {@link DataTable.defaults}.
13522.
         *  @type string
13523.
         *  @default two_button
13524.
         */
13525.
        "sPaginationType": "two_button",
13526.
    
13527.
        /**
13528.
         * The state duration (for `stateSave`) in seconds.
13529.
         * Note that this parameter will be set by the initialisation routine. To
13530.
         * set a default use {@link DataTable.defaults}.
13531.
         *  @type int
13532.
         *  @default 0
13533.
         */
13534.
        "iStateDuration": 0,
13535.
    
13536.
        /**
13537.
         * Array of callback functions for state saving. Each array element is an
13538.
         * object with the following parameters:
13539.
         *   <ul>
13540.
         *     <li>function:fn - function to call. Takes two parameters, oSettings
13541.
         *       and the JSON string to save that has been thus far created. Returns
13542.
         *       a JSON string to be inserted into a json object
13543.
         *       (i.e. '"param": [ 0, 1, 2]')</li>
13544.
         *     <li>string:sName - name of callback</li>
13545.
         *   </ul>
13546.
         *  @type array
13547.
         *  @default []
13548.
         */
13549.
        "aoStateSave": [],
13550.
    
13551.
        /**
13552.
         * Array of callback functions for state loading. Each array element is an
13553.
         * object with the following parameters:
13554.
         *   <ul>
13555.
         *     <li>function:fn - function to call. Takes two parameters, oSettings
13556.
         *       and the object stored. May return false to cancel state loading</li>
13557.
         *     <li>string:sName - name of callback</li>
13558.
         *   </ul>
13559.
         *  @type array
13560.
         *  @default []
13561.
         */
13562.
        "aoStateLoad": [],
13563.
    
13564.
        /**
13565.
         * State that was saved. Useful for back reference
13566.
         *  @type object
13567.
         *  @default null
13568.
         */
13569.
        "oSavedState": null,
13570.
    
13571.
        /**
13572.
         * State that was loaded. Useful for back reference
13573.
         *  @type object
13574.
         *  @default null
13575.
         */
13576.
        "oLoadedState": null,
13577.
    
13578.
        /**
13579.
         * Source url for AJAX data for the table.
13580.
         * Note that this parameter will be set by the initialisation routine. To
13581.
         * set a default use {@link DataTable.defaults}.
13582.
         *  @type string
13583.
         *  @default null
13584.
         */
13585.
        "sAjaxSource": null,
13586.
    
13587.
        /**
13588.
         * Property from a given object from which to read the table data from. This
13589.
         * can be an empty string (when not server-side processing), in which case
13590.
         * it is  assumed an an array is given directly.
13591.
         * Note that this parameter will be set by the initialisation routine. To
13592.
         * set a default use {@link DataTable.defaults}.
13593.
         *  @type string
13594.
         */
13595.
        "sAjaxDataProp": null,
13596.
    
13597.
        /**
13598.
         * Note if draw should be blocked while getting data
13599.
         *  @type boolean
13600.
         *  @default true
13601.
         */
13602.
        "bAjaxDataGet": true,
13603.
    
13604.
        /**
13605.
         * The last jQuery XHR object that was used for server-side data gathering.
13606.
         * This can be used for working with the XHR information in one of the
13607.
         * callbacks
13608.
         *  @type object
13609.
         *  @default null
13610.
         */
13611.
        "jqXHR": null,
13612.
    
13613.
        /**
13614.
         * JSON returned from the server in the last Ajax request
13615.
         *  @type object
13616.
         *  @default undefined
13617.
         */
13618.
        "json": undefined,
13619.
    
13620.
        /**
13621.
         * Data submitted as part of the last Ajax request
13622.
         *  @type object
13623.
         *  @default undefined
13624.
         */
13625.
        "oAjaxData": undefined,
13626.
    
13627.
        /**
13628.
         * Function to get the server-side data.
13629.
         * Note that this parameter will be set by the initialisation routine. To
13630.
         * set a default use {@link DataTable.defaults}.
13631.
         *  @type function
13632.
         */
13633.
        "fnServerData": null,
13634.
    
13635.
        /**
13636.
         * Functions which are called prior to sending an Ajax request so extra
13637.
         * parameters can easily be sent to the server
13638.
         *  @type array
13639.
         *  @default []
13640.
         */
13641.
        "aoServerParams": [],
13642.
    
13643.
        /**
13644.
         * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13645.
         * required).
13646.
         * Note that this parameter will be set by the initialisation routine. To
13647.
         * set a default use {@link DataTable.defaults}.
13648.
         *  @type string
13649.
         */
13650.
        "sServerMethod": null,
13651.
    
13652.
        /**
13653.
         * Format numbers for display.
13654.
         * Note that this parameter will be set by the initialisation routine. To
13655.
         * set a default use {@link DataTable.defaults}.
13656.
         *  @type function
13657.
         */
13658.
        "fnFormatNumber": null,
13659.
    
13660.
        /**
13661.
         * List of options that can be used for the user selectable length menu.
13662.
         * Note that this parameter will be set by the initialisation routine. To
13663.
         * set a default use {@link DataTable.defaults}.
13664.
         *  @type array
13665.
         *  @default []
13666.
         */
13667.
        "aLengthMenu": null,
13668.
    
13669.
        /**
13670.
         * Counter for the draws that the table does. Also used as a tracker for
13671.
         * server-side processing
13672.
         *  @type int
13673.
         *  @default 0
13674.
         */
13675.
        "iDraw": 0,
13676.
    
13677.
        /**
13678.
         * Indicate if a redraw is being done - useful for Ajax
13679.
         *  @type boolean
13680.
         *  @default false
13681.
         */
13682.
        "bDrawing": false,
13683.
    
13684.
        /**
13685.
         * Draw index (iDraw) of the last error when parsing the returned data
13686.
         *  @type int
13687.
         *  @default -1
13688.
         */
13689.
        "iDrawError": -1,
13690.
    
13691.
        /**
13692.
         * Paging display length
13693.
         *  @type int
13694.
         *  @default 10
13695.
         */
13696.
        "_iDisplayLength": 10,
13697.
    
13698.
        /**
13699.
         * Paging start point - aiDisplay index
13700.
         *  @type int
13701.
         *  @default 0
13702.
         */
13703.
        "_iDisplayStart": 0,
13704.
    
13705.
        /**
13706.
         * Server-side processing - number of records in the result set
13707.
         * (i.e. before filtering), Use fnRecordsTotal rather than
13708.
         * this property to get the value of the number of records, regardless of
13709.
         * the server-side processing setting.
13710.
         *  @type int
13711.
         *  @default 0
13712.
         *  @private
13713.
         */
13714.
        "_iRecordsTotal": 0,
13715.
    
13716.
        /**
13717.
         * Server-side processing - number of records in the current display set
13718.
         * (i.e. after filtering). Use fnRecordsDisplay rather than
13719.
         * this property to get the value of the number of records, regardless of
13720.
         * the server-side processing setting.
13721.
         *  @type boolean
13722.
         *  @default 0
13723.
         *  @private
13724.
         */
13725.
        "_iRecordsDisplay": 0,
13726.
    
13727.
        /**
13728.
         * The classes to use for the table
13729.
         *  @type object
13730.
         *  @default {}
13731.
         */
13732.
        "oClasses": {},
13733.
    
13734.
        /**
13735.
         * Flag attached to the settings object so you can check in the draw
13736.
         * callback if filtering has been done in the draw. Deprecated in favour of
13737.
         * events.
13738.
         *  @type boolean
13739.
         *  @default false
13740.
         *  @deprecated
13741.
         */
13742.
        "bFiltered": false,
13743.
    
13744.
        /**
13745.
         * Flag attached to the settings object so you can check in the draw
13746.
         * callback if sorting has been done in the draw. Deprecated in favour of
13747.
         * events.
13748.
         *  @type boolean
13749.
         *  @default false
13750.
         *  @deprecated
13751.
         */
13752.
        "bSorted": false,
13753.
    
13754.
        /**
13755.
         * Indicate that if multiple rows are in the header and there is more than
13756.
         * one unique cell per column, if the top one (true) or bottom one (false)
13757.
         * should be used for sorting / title by DataTables.
13758.
         * Note that this parameter will be set by the initialisation routine. To
13759.
         * set a default use {@link DataTable.defaults}.
13760.
         *  @type boolean
13761.
         */
13762.
        "bSortCellsTop": null,
13763.
    
13764.
        /**
13765.
         * Initialisation object that is used for the table
13766.
         *  @type object
13767.
         *  @default null
13768.
         */
13769.
        "oInit": null,
13770.
    
13771.
        /**
13772.
         * Destroy callback functions - for plug-ins to attach themselves to the
13773.
         * destroy so they can clean up markup and events.
13774.
         *  @type array
13775.
         *  @default []
13776.
         */
13777.
        "aoDestroyCallback": [],
13778.
    
13779.
    
13780.
        /**
13781.
         * Get the number of records in the current record set, before filtering
13782.
         *  @type function
13783.
         */
13784.
        "fnRecordsTotal": function ()
13785.
        {
13786.
            return _fnDataSource( this ) == 'ssp' ?
13787.
                this._iRecordsTotal * 1 :
13788.
                this.aiDisplayMaster.length;
13789.
        },
13790.
    
13791.
        /**
13792.
         * Get the number of records in the current record set, after filtering
13793.
         *  @type function
13794.
         */
13795.
        "fnRecordsDisplay": function ()
13796.
        {
13797.
            return _fnDataSource( this ) == 'ssp' ?
13798.
                this._iRecordsDisplay * 1 :
13799.
                this.aiDisplay.length;
13800.
        },
13801.
    
13802.
        /**
13803.
         * Get the display end point - aiDisplay index
13804.
         *  @type function
13805.
         */
13806.
        "fnDisplayEnd": function ()
13807.
        {
13808.
            var
13809.
                len      = this._iDisplayLength,
13810.
                start    = this._iDisplayStart,
13811.
                calc     = start + len,
13812.
                records  = this.aiDisplay.length,
13813.
                features = this.oFeatures,
13814.
                paginate = features.bPaginate;
13815.
    
13816.
            if ( features.bServerSide ) {
13817.
                return paginate === false || len === -1 ?
13818.
                    start + records :
13819.
                    Math.min( start+len, this._iRecordsDisplay );
13820.
            }
13821.
            else {
13822.
                return ! paginate || calc>records || len===-1 ?
13823.
                    records :
13824.
                    calc;
13825.
            }
13826.
        },
13827.
    
13828.
        /**
13829.
         * The DataTables object for this table
13830.
         *  @type object
13831.
         *  @default null
13832.
         */
13833.
        "oInstance": null,
13834.
    
13835.
        /**
13836.
         * Unique identifier for each instance of the DataTables object. If there
13837.
         * is an ID on the table node, then it takes that value, otherwise an
13838.
         * incrementing internal counter is used.
13839.
         *  @type string
13840.
         *  @default null
13841.
         */
13842.
        "sInstance": null,
13843.
    
13844.
        /**
13845.
         * tabindex attribute value that is added to DataTables control elements, allowing
13846.
         * keyboard navigation of the table and its controls.
13847.
         */
13848.
        "iTabIndex": 0,
13849.
    
13850.
        /**
13851.
         * DIV container for the footer scrolling table if scrolling
13852.
         */
13853.
        "nScrollHead": null,
13854.
    
13855.
        /**
13856.
         * DIV container for the footer scrolling table if scrolling
13857.
         */
13858.
        "nScrollFoot": null,
13859.
    
13860.
        /**
13861.
         * Last applied sort
13862.
         *  @type array
13863.
         *  @default []
13864.
         */
13865.
        "aLastSort": [],
13866.
    
13867.
        /**
13868.
         * Stored plug-in instances
13869.
         *  @type object
13870.
         *  @default {}
13871.
         */
13872.
        "oPlugins": {},
13873.
    
13874.
        /**
13875.
         * Function used to get a row's id from the row's data
13876.
         *  @type function
13877.
         *  @default null
13878.
         */
13879.
        "rowIdFn": null,
13880.
    
13881.
        /**
13882.
         * Data location where to store a row's id
13883.
         *  @type string
13884.
         *  @default null
13885.
         */
13886.
        "rowId": null
13887.
    };
13888.
 
13889.
    /**
13890.
     * Extension object for DataTables that is used to provide all extension
13891.
     * options.
13892.
     *
13893.
     * Note that the `DataTable.ext` object is available through
13894.
     * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13895.
     * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13896.
     *  @namespace
13897.
     *  @extends DataTable.models.ext
13898.
     */
13899.
    
13900.
    
13901.
    /**
13902.
     * DataTables extensions
13903.
     * 
13904.
     * This namespace acts as a collection area for plug-ins that can be used to
13905.
     * extend DataTables capabilities. Indeed many of the build in methods
13906.
     * use this method to provide their own capabilities (sorting methods for
13907.
     * example).
13908.
     *
13909.
     * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13910.
     * reasons
13911.
     *
13912.
     *  @namespace
13913.
     */
13914.
    DataTable.ext = _ext = {
13915.
        /**
13916.
         * Buttons. For use with the Buttons extension for DataTables. This is
13917.
         * defined here so other extensions can define buttons regardless of load
13918.
         * order. It is _not_ used by DataTables core.
13919.
         *
13920.
         *  @type object
13921.
         *  @default {}
13922.
         */
13923.
        buttons: {},
13924.
    
13925.
    
13926.
        /**
13927.
         * Element class names
13928.
         *
13929.
         *  @type object
13930.
         *  @default {}
13931.
         */
13932.
        classes: {},
13933.
    
13934.
    
13935.
        /**
13936.
         * DataTables build type (expanded by the download builder)
13937.
         *
13938.
         *  @type string
13939.
         */
13940.
        build:"dt/dt-1.10.21",
13941.
    
13942.
    
13943.
        /**
13944.
         * Error reporting.
13945.
         * 
13946.
         * How should DataTables report an error. Can take the value 'alert',
13947.
         * 'throw', 'none' or a function.
13948.
         *
13949.
         *  @type string|function
13950.
         *  @default alert
13951.
         */
13952.
        errMode: "alert",
13953.
    
13954.
    
13955.
        /**
13956.
         * Feature plug-ins.
13957.
         * 
13958.
         * This is an array of objects which describe the feature plug-ins that are
13959.
         * available to DataTables. These feature plug-ins are then available for
13960.
         * use through the `dom` initialisation option.
13961.
         * 
13962.
         * Each feature plug-in is described by an object which must have the
13963.
         * following properties:
13964.
         * 
13965.
         * * `fnInit` - function that is used to initialise the plug-in,
13966.
         * * `cFeature` - a character so the feature can be enabled by the `dom`
13967.
         *   instillation option. This is case sensitive.
13968.
         *
13969.
         * The `fnInit` function has the following input parameters:
13970.
         *
13971.
         * 1. `{object}` DataTables settings object: see
13972.
         *    {@link DataTable.models.oSettings}
13973.
         *
13974.
         * And the following return is expected:
13975.
         * 
13976.
         * * {node|null} The element which contains your feature. Note that the
13977.
         *   return may also be void if your plug-in does not require to inject any
13978.
         *   DOM elements into DataTables control (`dom`) - for example this might
13979.
         *   be useful when developing a plug-in which allows table control via
13980.
         *   keyboard entry
13981.
         *
13982.
         *  @type array
13983.
         *
13984.
         *  @example
13985.
         *    $.fn.dataTable.ext.features.push( {
13986.
         *      "fnInit": function( oSettings ) {
13987.
         *        return new TableTools( { "oDTSettings": oSettings } );
13988.
         *      },
13989.
         *      "cFeature": "T"
13990.
         *    } );
13991.
         */
13992.
        feature: [],
13993.
    
13994.
    
13995.
        /**
13996.
         * Row searching.
13997.
         * 
13998.
         * This method of searching is complimentary to the default type based
13999.
         * searching, and a lot more comprehensive as it allows you complete control
14000.
         * over the searching logic. Each element in this array is a function
14001.
         * (parameters described below) that is called for every row in the table,
14002.
         * and your logic decides if it should be included in the searching data set
14003.
         * or not.
14004.
         *
14005.
         * Searching functions have the following input parameters:
14006.
         *
14007.
         * 1. `{object}` DataTables settings object: see
14008.
         *    {@link DataTable.models.oSettings}
14009.
         * 2. `{array|object}` Data for the row to be processed (same as the
14010.
         *    original format that was passed in as the data source, or an array
14011.
         *    from a DOM data source
14012.
         * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
14013.
         *    can be useful to retrieve the `TR` element if you need DOM interaction.
14014.
         *
14015.
         * And the following return is expected:
14016.
         *
14017.
         * * {boolean} Include the row in the searched result set (true) or not
14018.
         *   (false)
14019.
         *
14020.
         * Note that as with the main search ability in DataTables, technically this
14021.
         * is "filtering", since it is subtractive. However, for consistency in
14022.
         * naming we call it searching here.
14023.
         *
14024.
         *  @type array
14025.
         *  @default []
14026.
         *
14027.
         *  @example
14028.
         *    // The following example shows custom search being applied to the
14029.
         *    // fourth column (i.e. the data[3] index) based on two input values
14030.
         *    // from the end-user, matching the data in a certain range.
14031.
         *    $.fn.dataTable.ext.search.push(
14032.
         *      function( settings, data, dataIndex ) {
14033.
         *        var min = document.getElementById('min').value * 1;
14034.
         *        var max = document.getElementById('max').value * 1;
14035.
         *        var version = data[3] == "-" ? 0 : data[3]*1;
14036.
         *
14037.
         *        if ( min == "" && max == "" ) {
14038.
         *          return true;
14039.
         *        }
14040.
         *        else if ( min == "" && version < max ) {
14041.
         *          return true;
14042.
         *        }
14043.
         *        else if ( min < version && "" == max ) {
14044.
         *          return true;
14045.
         *        }
14046.
         *        else if ( min < version && version < max ) {
14047.
         *          return true;
14048.
         *        }
14049.
         *        return false;
14050.
         *      }
14051.
         *    );
14052.
         */
14053.
        search: [],
14054.
    
14055.
    
14056.
        /**
14057.
         * Selector extensions
14058.
         *
14059.
         * The `selector` option can be used to extend the options available for the
14060.
         * selector modifier options (`selector-modifier` object data type) that
14061.
         * each of the three built in selector types offer (row, column and cell +
14062.
         * their plural counterparts). For example the Select extension uses this
14063.
         * mechanism to provide an option to select only rows, columns and cells
14064.
         * that have been marked as selected by the end user (`{selected: true}`),
14065.
         * which can be used in conjunction with the existing built in selector
14066.
         * options.
14067.
         *
14068.
         * Each property is an array to which functions can be pushed. The functions
14069.
         * take three attributes:
14070.
         *
14071.
         * * Settings object for the host table
14072.
         * * Options object (`selector-modifier` object type)
14073.
         * * Array of selected item indexes
14074.
         *
14075.
         * The return is an array of the resulting item indexes after the custom
14076.
         * selector has been applied.
14077.
         *
14078.
         *  @type object
14079.
         */
14080.
        selector: {
14081.
            cell: [],
14082.
            column: [],
14083.
            row: []
14084.
        },
14085.
    
14086.
    
14087.
        /**
14088.
         * Internal functions, exposed for used in plug-ins.
14089.
         * 
14090.
         * Please note that you should not need to use the internal methods for
14091.
         * anything other than a plug-in (and even then, try to avoid if possible).
14092.
         * The internal function may change between releases.
14093.
         *
14094.
         *  @type object
14095.
         *  @default {}
14096.
         */
14097.
        internal: {},
14098.
    
14099.
    
14100.
        /**
14101.
         * Legacy configuration options. Enable and disable legacy options that
14102.
         * are available in DataTables.
14103.
         *
14104.
         *  @type object
14105.
         */
14106.
        legacy: {
14107.
            /**
14108.
             * Enable / disable DataTables 1.9 compatible server-side processing
14109.
             * requests
14110.
             *
14111.
             *  @type boolean
14112.
             *  @default null
14113.
             */
14114.
            ajax: null
14115.
        },
14116.
    
14117.
    
14118.
        /**
14119.
         * Pagination plug-in methods.
14120.
         * 
14121.
         * Each entry in this object is a function and defines which buttons should
14122.
         * be shown by the pagination rendering method that is used for the table:
14123.
         * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
14124.
         * buttons are displayed in the document, while the functions here tell it
14125.
         * what buttons to display. This is done by returning an array of button
14126.
         * descriptions (what each button will do).
14127.
         *
14128.
         * Pagination types (the four built in options and any additional plug-in
14129.
         * options defined here) can be used through the `paginationType`
14130.
         * initialisation parameter.
14131.
         *
14132.
         * The functions defined take two parameters:
14133.
         *
14134.
         * 1. `{int} page` The current page index
14135.
         * 2. `{int} pages` The number of pages in the table
14136.
         *
14137.
         * Each function is expected to return an array where each element of the
14138.
         * array can be one of:
14139.
         *
14140.
         * * `first` - Jump to first page when activated
14141.
         * * `last` - Jump to last page when activated
14142.
         * * `previous` - Show previous page when activated
14143.
         * * `next` - Show next page when activated
14144.
         * * `{int}` - Show page of the index given
14145.
         * * `{array}` - A nested array containing the above elements to add a
14146.
         *   containing 'DIV' element (might be useful for styling).
14147.
         *
14148.
         * Note that DataTables v1.9- used this object slightly differently whereby
14149.
         * an object with two functions would be defined for each plug-in. That
14150.
         * ability is still supported by DataTables 1.10+ to provide backwards
14151.
         * compatibility, but this option of use is now decremented and no longer
14152.
         * documented in DataTables 1.10+.
14153.
         *
14154.
         *  @type object
14155.
         *  @default {}
14156.
         *
14157.
         *  @example
14158.
         *    // Show previous, next and current page buttons only
14159.
         *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
14160.
         *      return [ 'previous', page, 'next' ];
14161.
         *    };
14162.
         */
14163.
        pager: {},
14164.
    
14165.
    
14166.
        renderer: {
14167.
            pageButton: {},
14168.
            header: {}
14169.
        },
14170.
    
14171.
    
14172.
        /**
14173.
         * Ordering plug-ins - custom data source
14174.
         * 
14175.
         * The extension options for ordering of data available here is complimentary
14176.
         * to the default type based ordering that DataTables typically uses. It
14177.
         * allows much greater control over the the data that is being used to
14178.
         * order a column, but is necessarily therefore more complex.
14179.
         * 
14180.
         * This type of ordering is useful if you want to do ordering based on data
14181.
         * live from the DOM (for example the contents of an 'input' element) rather
14182.
         * than just the static string that DataTables knows of.
14183.
         * 
14184.
         * The way these plug-ins work is that you create an array of the values you
14185.
         * wish to be ordering for the column in question and then return that
14186.
         * array. The data in the array much be in the index order of the rows in
14187.
         * the table (not the currently ordering order!). Which order data gathering
14188.
         * function is run here depends on the `dt-init columns.orderDataType`
14189.
         * parameter that is used for the column (if any).
14190.
         *
14191.
         * The functions defined take two parameters:
14192.
         *
14193.
         * 1. `{object}` DataTables settings object: see
14194.
         *    {@link DataTable.models.oSettings}
14195.
         * 2. `{int}` Target column index
14196.
         *
14197.
         * Each function is expected to return an array:
14198.
         *
14199.
         * * `{array}` Data for the column to be ordering upon
14200.
         *
14201.
         *  @type array
14202.
         *
14203.
         *  @example
14204.
         *    // Ordering using `input` node values
14205.
         *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
14206.
         *    {
14207.
         *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
14208.
         *        return $('input', td).val();
14209.
         *      } );
14210.
         *    }
14211.
         */
14212.
        order: {},
14213.
    
14214.
    
14215.
        /**
14216.
         * Type based plug-ins.
14217.
         *
14218.
         * Each column in DataTables has a type assigned to it, either by automatic
14219.
         * detection or by direct assignment using the `type` option for the column.
14220.
         * The type of a column will effect how it is ordering and search (plug-ins
14221.
         * can also make use of the column type if required).
14222.
         *
14223.
         * @namespace
14224.
         */
14225.
        type: {
14226.
            /**
14227.
             * Type detection functions.
14228.
             *
14229.
             * The functions defined in this object are used to automatically detect
14230.
             * a column's type, making initialisation of DataTables super easy, even
14231.
             * when complex data is in the table.
14232.
             *
14233.
             * The functions defined take two parameters:
14234.
             *
14235.
             *  1. `{*}` Data from the column cell to be analysed
14236.
             *  2. `{settings}` DataTables settings object. This can be used to
14237.
             *     perform context specific type detection - for example detection
14238.
             *     based on language settings such as using a comma for a decimal
14239.
             *     place. Generally speaking the options from the settings will not
14240.
             *     be required
14241.
             *
14242.
             * Each function is expected to return:
14243.
             *
14244.
             * * `{string|null}` Data type detected, or null if unknown (and thus
14245.
             *   pass it on to the other type detection functions.
14246.
             *
14247.
             *  @type array
14248.
             *
14249.
             *  @example
14250.
             *    // Currency type detection plug-in:
14251.
             *    $.fn.dataTable.ext.type.detect.push(
14252.
             *      function ( data, settings ) {
14253.
             *        // Check the numeric part
14254.
             *        if ( ! data.substring(1).match(/[0-9]/) ) {
14255.
             *          return null;
14256.
             *        }
14257.
             *
14258.
             *        // Check prefixed by currency
14259.
             *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
14260.
             *          return 'currency';
14261.
             *        }
14262.
             *        return null;
14263.
             *      }
14264.
             *    );
14265.
             */
14266.
            detect: [],
14267.
    
14268.
    
14269.
            /**
14270.
             * Type based search formatting.
14271.
             *
14272.
             * The type based searching functions can be used to pre-format the
14273.
             * data to be search on. For example, it can be used to strip HTML
14274.
             * tags or to de-format telephone numbers for numeric only searching.
14275.
             *
14276.
             * Note that is a search is not defined for a column of a given type,
14277.
             * no search formatting will be performed.
14278.
             * 
14279.
             * Pre-processing of searching data plug-ins - When you assign the sType
14280.
             * for a column (or have it automatically detected for you by DataTables
14281.
             * or a type detection plug-in), you will typically be using this for
14282.
             * custom sorting, but it can also be used to provide custom searching
14283.
             * by allowing you to pre-processing the data and returning the data in
14284.
             * the format that should be searched upon. This is done by adding
14285.
             * functions this object with a parameter name which matches the sType
14286.
             * for that target column. This is the corollary of <i>afnSortData</i>
14287.
             * for searching data.
14288.
             *
14289.
             * The functions defined take a single parameter:
14290.
             *
14291.
             *  1. `{*}` Data from the column cell to be prepared for searching
14292.
             *
14293.
             * Each function is expected to return:
14294.
             *
14295.
             * * `{string|null}` Formatted string that will be used for the searching.
14296.
             *
14297.
             *  @type object
14298.
             *  @default {}
14299.
             *
14300.
             *  @example
14301.
             *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14302.
             *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14303.
             *    }
14304.
             */
14305.
            search: {},
14306.
    
14307.
    
14308.
            /**
14309.
             * Type based ordering.
14310.
             *
14311.
             * The column type tells DataTables what ordering to apply to the table
14312.
             * when a column is sorted upon. The order for each type that is defined,
14313.
             * is defined by the functions available in this object.
14314.
             *
14315.
             * Each ordering option can be described by three properties added to
14316.
             * this object:
14317.
             *
14318.
             * * `{type}-pre` - Pre-formatting function
14319.
             * * `{type}-asc` - Ascending order function
14320.
             * * `{type}-desc` - Descending order function
14321.
             *
14322.
             * All three can be used together, only `{type}-pre` or only
14323.
             * `{type}-asc` and `{type}-desc` together. It is generally recommended
14324.
             * that only `{type}-pre` is used, as this provides the optimal
14325.
             * implementation in terms of speed, although the others are provided
14326.
             * for compatibility with existing Javascript sort functions.
14327.
             *
14328.
             * `{type}-pre`: Functions defined take a single parameter:
14329.
             *
14330.
             *  1. `{*}` Data from the column cell to be prepared for ordering
14331.
             *
14332.
             * And return:
14333.
             *
14334.
             * * `{*}` Data to be sorted upon
14335.
             *
14336.
             * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14337.
             * functions, taking two parameters:
14338.
             *
14339.
             *  1. `{*}` Data to compare to the second parameter
14340.
             *  2. `{*}` Data to compare to the first parameter
14341.
             *
14342.
             * And returning:
14343.
             *
14344.
             * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14345.
             *   than the second parameter, ===0 if the two parameters are equal and
14346.
             *   >0 if the first parameter should be sorted height than the second
14347.
             *   parameter.
14348.
             * 
14349.
             *  @type object
14350.
             *  @default {}
14351.
             *
14352.
             *  @example
14353.
             *    // Numeric ordering of formatted numbers with a pre-formatter
14354.
             *    $.extend( $.fn.dataTable.ext.type.order, {
14355.
             *      "string-pre": function(x) {
14356.
             *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14357.
             *        return parseFloat( a );
14358.
             *      }
14359.
             *    } );
14360.
             *
14361.
             *  @example
14362.
             *    // Case-sensitive string ordering, with no pre-formatting method
14363.
             *    $.extend( $.fn.dataTable.ext.order, {
14364.
             *      "string-case-asc": function(x,y) {
14365.
             *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14366.
             *      },
14367.
             *      "string-case-desc": function(x,y) {
14368.
             *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14369.
             *      }
14370.
             *    } );
14371.
             */
14372.
            order: {}
14373.
        },
14374.
    
14375.
        /**
14376.
         * Unique DataTables instance counter
14377.
         *
14378.
         * @type int
14379.
         * @private
14380.
         */
14381.
        _unique: 0,
14382.
    
14383.
    
14384.
        //
14385.
        // Depreciated
14386.
        // The following properties are retained for backwards compatiblity only.
14387.
        // The should not be used in new projects and will be removed in a future
14388.
        // version
14389.
        //
14390.
    
14391.
        /**
14392.
         * Version check function.
14393.
         *  @type function
14394.
         *  @depreciated Since 1.10
14395.
         */
14396.
        fnVersionCheck: DataTable.fnVersionCheck,
14397.
    
14398.
    
14399.
        /**
14400.
         * Index for what 'this' index API functions should use
14401.
         *  @type int
14402.
         *  @deprecated Since v1.10
14403.
         */
14404.
        iApiIndex: 0,
14405.
    
14406.
    
14407.
        /**
14408.
         * jQuery UI class container
14409.
         *  @type object
14410.
         *  @deprecated Since v1.10
14411.
         */
14412.
        oJUIClasses: {},
14413.
    
14414.
    
14415.
        /**
14416.
         * Software version
14417.
         *  @type string
14418.
         *  @deprecated Since v1.10
14419.
         */
14420.
        sVersion: DataTable.version
14421.
    };
14422.
    
14423.
    
14424.
    //
14425.
    // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14426.
    //
14427.
    $.extend( _ext, {
14428.
        afnFiltering: _ext.search,
14429.
        aTypes:       _ext.type.detect,
14430.
        ofnSearch:    _ext.type.search,
14431.
        oSort:        _ext.type.order,
14432.
        afnSortData:  _ext.order,
14433.
        aoFeatures:   _ext.feature,
14434.
        oApi:         _ext.internal,
14435.
        oStdClasses:  _ext.classes,
14436.
        oPagination:  _ext.pager
14437.
    } );
14438.
    
14439.
    
14440.
    $.extend( DataTable.ext.classes, {
14441.
        "sTable": "dataTable",
14442.
        "sNoFooter": "no-footer",
14443.
    
14444.
        /* Paging buttons */
14445.
        "sPageButton": "paginate_button",
14446.
        "sPageButtonActive": "current",
14447.
        "sPageButtonDisabled": "disabled",
14448.
    
14449.
        /* Striping classes */
14450.
        "sStripeOdd": "odd",
14451.
        "sStripeEven": "even",
14452.
    
14453.
        /* Empty row */
14454.
        "sRowEmpty": "dataTables_empty",
14455.
    
14456.
        /* Features */
14457.
        "sWrapper": "dataTables_wrapper",
14458.
        "sFilter": "dataTables_filter",
14459.
        "sInfo": "dataTables_info",
14460.
        "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14461.
        "sLength": "dataTables_length",
14462.
        "sProcessing": "dataTables_processing",
14463.
    
14464.
        /* Sorting */
14465.
        "sSortAsc": "sorting_asc",
14466.
        "sSortDesc": "sorting_desc",
14467.
        "sSortable": "sorting", /* Sortable in both directions */
14468.
        "sSortableAsc": "sorting_asc_disabled",
14469.
        "sSortableDesc": "sorting_desc_disabled",
14470.
        "sSortableNone": "sorting_disabled",
14471.
        "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14472.
    
14473.
        /* Filtering */
14474.
        "sFilterInput": "",
14475.
    
14476.
        /* Page length */
14477.
        "sLengthSelect": "",
14478.
    
14479.
        /* Scrolling */
14480.
        "sScrollWrapper": "dataTables_scroll",
14481.
        "sScrollHead": "dataTables_scrollHead",
14482.
        "sScrollHeadInner": "dataTables_scrollHeadInner",
14483.
        "sScrollBody": "dataTables_scrollBody",
14484.
        "sScrollFoot": "dataTables_scrollFoot",
14485.
        "sScrollFootInner": "dataTables_scrollFootInner",
14486.
    
14487.
        /* Misc */
14488.
        "sHeaderTH": "",
14489.
        "sFooterTH": "",
14490.
    
14491.
        // Deprecated
14492.
        "sSortJUIAsc": "",
14493.
        "sSortJUIDesc": "",
14494.
        "sSortJUI": "",
14495.
        "sSortJUIAscAllowed": "",
14496.
        "sSortJUIDescAllowed": "",
14497.
        "sSortJUIWrapper": "",
14498.
        "sSortIcon": "",
14499.
        "sJUIHeader": "",
14500.
        "sJUIFooter": ""
14501.
    } );
14502.
    
14503.
    
14504.
    var extPagination = DataTable.ext.pager;
14505.
    
14506.
    function _numbers ( page, pages ) {
14507.
        var
14508.
            numbers = [],
14509.
            buttons = extPagination.numbers_length,
14510.
            half = Math.floor( buttons / 2 ),
14511.
            i = 1;
14512.
    
14513.
        if ( pages <= buttons ) {
14514.
            numbers = _range( 0, pages );
14515.
        }
14516.
        else if ( page <= half ) {
14517.
            numbers = _range( 0, buttons-2 );
14518.
            numbers.push( 'ellipsis' );
14519.
            numbers.push( pages-1 );
14520.
        }
14521.
        else if ( page >= pages - 1 - half ) {
14522.
            numbers = _range( pages-(buttons-2), pages );
14523.
            numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14524.
            numbers.splice( 0, 0, 0 );
14525.
        }
14526.
        else {
14527.
            numbers = _range( page-half+2, page+half-1 );
14528.
            numbers.push( 'ellipsis' );
14529.
            numbers.push( pages-1 );
14530.
            numbers.splice( 0, 0, 'ellipsis' );
14531.
            numbers.splice( 0, 0, 0 );
14532.
        }
14533.
    
14534.
        numbers.DT_el = 'span';
14535.
        return numbers;
14536.
    }
14537.
    
14538.
    
14539.
    $.extend( extPagination, {
14540.
        simple: function ( page, pages ) {
14541.
            return [ 'previous', 'next' ];
14542.
        },
14543.
    
14544.
        full: function ( page, pages ) {
14545.
            return [  'first', 'previous', 'next', 'last' ];
14546.
        },
14547.
    
14548.
        numbers: function ( page, pages ) {
14549.
            return [ _numbers(page, pages) ];
14550.
        },
14551.
    
14552.
        simple_numbers: function ( page, pages ) {
14553.
            return [ 'previous', _numbers(page, pages), 'next' ];
14554.
        },
14555.
    
14556.
        full_numbers: function ( page, pages ) {
14557.
            return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14558.
        },
14559.
        
14560.
        first_last_numbers: function (page, pages) {
14561.
             return ['first', _numbers(page, pages), 'last'];
14562.
         },
14563.
    
14564.
        // For testing and plug-ins to use
14565.
        _numbers: _numbers,
14566.
    
14567.
        // Number of number buttons (including ellipsis) to show. _Must be odd!_
14568.
        numbers_length: 7
14569.
    } );
14570.
    
14571.
    
14572.
    $.extend( true, DataTable.ext.renderer, {
14573.
        pageButton: {
14574.
            _: function ( settings, host, idx, buttons, page, pages ) {
14575.
                var classes = settings.oClasses;
14576.
                var lang = settings.oLanguage.oPaginate;
14577.
                var aria = settings.oLanguage.oAria.paginate || {};
14578.
                var btnDisplay, btnClass, counter=0;
14579.
    
14580.
                var attach = function( container, buttons ) {
14581.
                    var i, ien, node, button, tabIndex;
14582.
                    var disabledClass = classes.sPageButtonDisabled;
14583.
                    var clickHandler = function ( e ) {
14584.
                        _fnPageChange( settings, e.data.action, true );
14585.
                    };
14586.
    
14587.
                    for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14588.
                        button = buttons[i];
14589.
    
14590.
                        if ( $.isArray( button ) ) {
14591.
                            var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14592.
                                .appendTo( container );
14593.
                            attach( inner, button );
14594.
                        }
14595.
                        else {
14596.
                            btnDisplay = null;
14597.
                            btnClass = button;
14598.
                            tabIndex = settings.iTabIndex;
14599.
    
14600.
                            switch ( button ) {
14601.
                                case 'ellipsis':
14602.
                                    container.append('<span class="ellipsis">&#x2026;</span>');
14603.
                                    break;
14604.
    
14605.
                                case 'first':
14606.
                                    btnDisplay = lang.sFirst;
14607.
    
14608.
                                    if ( page === 0 ) {
14609.
                                        tabIndex = -1;
14610.
                                        btnClass += ' ' + disabledClass;
14611.
                                    }
14612.
                                    break;
14613.
    
14614.
                                case 'previous':
14615.
                                    btnDisplay = lang.sPrevious;
14616.
    
14617.
                                    if ( page === 0 ) {
14618.
                                        tabIndex = -1;
14619.
                                        btnClass += ' ' + disabledClass;
14620.
                                    }
14621.
                                    break;
14622.
    
14623.
                                case 'next':
14624.
                                    btnDisplay = lang.sNext;
14625.
    
14626.
                                    if ( pages === 0 || page === pages-1 ) {
14627.
                                        tabIndex = -1;
14628.
                                        btnClass += ' ' + disabledClass;
14629.
                                    }
14630.
                                    break;
14631.
    
14632.
                                case 'last':
14633.
                                    btnDisplay = lang.sLast;
14634.
    
14635.
                                    if ( page === pages-1 ) {
14636.
                                        tabIndex = -1;
14637.
                                        btnClass += ' ' + disabledClass;
14638.
                                    }
14639.
                                    break;
14640.
    
14641.
                                default:
14642.
                                    btnDisplay = button + 1;
14643.
                                    btnClass = page === button ?
14644.
                                        classes.sPageButtonActive : '';
14645.
                                    break;
14646.
                            }
14647.
    
14648.
                            if ( btnDisplay !== null ) {
14649.
                                node = $('<a>', {
14650.
                                        'class': classes.sPageButton+' '+btnClass,
14651.
                                        'aria-controls': settings.sTableId,
14652.
                                        'aria-label': aria[ button ],
14653.
                                        'data-dt-idx': counter,
14654.
                                        'tabindex': tabIndex,
14655.
                                        'id': idx === 0 && typeof button === 'string' ?
14656.
                                            settings.sTableId +'_'+ button :
14657.
                                            null
14658.
                                    } )
14659.
                                    .html( btnDisplay )
14660.
                                    .appendTo( container );
14661.
    
14662.
                                _fnBindAction(
14663.
                                    node, {action: button}, clickHandler
14664.
                                );
14665.
    
14666.
                                counter++;
14667.
                            }
14668.
                        }
14669.
                    }
14670.
                };
14671.
    
14672.
                // IE9 throws an 'unknown error' if document.activeElement is used
14673.
                // inside an iframe or frame. Try / catch the error. Not good for
14674.
                // accessibility, but neither are frames.
14675.
                var activeEl;
14676.
    
14677.
                try {
14678.
                    // Because this approach is destroying and recreating the paging
14679.
                    // elements, focus is lost on the select button which is bad for
14680.
                    // accessibility. So we want to restore focus once the draw has
14681.
                    // completed
14682.
                    activeEl = $(host).find(document.activeElement).data('dt-idx');
14683.
                }
14684.
                catch (e) {}
14685.
    
14686.
                attach( $(host).empty(), buttons );
14687.
    
14688.
                if ( activeEl !== undefined ) {
14689.
                    $(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
14690.
                }
14691.
            }
14692.
        }
14693.
    } );
14694.
    
14695.
    
14696.
    
14697.
    // Built in type detection. See model.ext.aTypes for information about
14698.
    // what is required from this methods.
14699.
    $.extend( DataTable.ext.type.detect, [
14700.
        // Plain numbers - first since V8 detects some plain numbers as dates
14701.
        // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14702.
        function ( d, settings )
14703.
        {
14704.
            var decimal = settings.oLanguage.sDecimal;
14705.
            return _isNumber( d, decimal ) ? 'num'+decimal : null;
14706.
        },
14707.
    
14708.
        // Dates (only those recognised by the browser's Date.parse)
14709.
        function ( d, settings )
14710.
        {
14711.
            // V8 tries _very_ hard to make a string passed into `Date.parse()`
14712.
            // valid, so we need to use a regex to restrict date formats. Use a
14713.
            // plug-in for anything other than ISO8601 style strings
14714.
            if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
14715.
                return null;
14716.
            }
14717.
            var parsed = Date.parse(d);
14718.
            return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14719.
        },
14720.
    
14721.
        // Formatted numbers
14722.
        function ( d, settings )
14723.
        {
14724.
            var decimal = settings.oLanguage.sDecimal;
14725.
            return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14726.
        },
14727.
    
14728.
        // HTML numeric
14729.
        function ( d, settings )
14730.
        {
14731.
            var decimal = settings.oLanguage.sDecimal;
14732.
            return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14733.
        },
14734.
    
14735.
        // HTML numeric, formatted
14736.
        function ( d, settings )
14737.
        {
14738.
            var decimal = settings.oLanguage.sDecimal;
14739.
            return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14740.
        },
14741.
    
14742.
        // HTML (this is strict checking - there must be html)
14743.
        function ( d, settings )
14744.
        {
14745.
            return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14746.
                'html' : null;
14747.
        }
14748.
    ] );
14749.
    
14750.
    
14751.
    
14752.
    // Filter formatting functions. See model.ext.ofnSearch for information about
14753.
    // what is required from these methods.
14754.
    // 
14755.
    // Note that additional search methods are added for the html numbers and
14756.
    // html formatted numbers by `_addNumericSort()` when we know what the decimal
14757.
    // place is
14758.
    
14759.
    
14760.
    $.extend( DataTable.ext.type.search, {
14761.
        html: function ( data ) {
14762.
            return _empty(data) ?
14763.
                data :
14764.
                typeof data === 'string' ?
14765.
                    data
14766.
                        .replace( _re_new_lines, " " )
14767.
                        .replace( _re_html, "" ) :
14768.
                    '';
14769.
        },
14770.
    
14771.
        string: function ( data ) {
14772.
            return _empty(data) ?
14773.
                data :
14774.
                typeof data === 'string' ?
14775.
                    data.replace( _re_new_lines, " " ) :
14776.
                    data;
14777.
        }
14778.
    } );
14779.
    
14780.
    
14781.
    
14782.
    var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14783.
        if ( d !== 0 && (!d || d === '-') ) {
14784.
            return -Infinity;
14785.
        }
14786.
    
14787.
        // If a decimal place other than `.` is used, it needs to be given to the
14788.
        // function so we can detect it and replace with a `.` which is the only
14789.
        // decimal place Javascript recognises - it is not locale aware.
14790.
        if ( decimalPlace ) {
14791.
            d = _numToDecimal( d, decimalPlace );
14792.
        }
14793.
    
14794.
        if ( d.replace ) {
14795.
            if ( re1 ) {
14796.
                d = d.replace( re1, '' );
14797.
            }
14798.
    
14799.
            if ( re2 ) {
14800.
                d = d.replace( re2, '' );
14801.
            }
14802.
        }
14803.
    
14804.
        return d * 1;
14805.
    };
14806.
    
14807.
    
14808.
    // Add the numeric 'deformatting' functions for sorting and search. This is done
14809.
    // in a function to provide an easy ability for the language options to add
14810.
    // additional methods if a non-period decimal place is used.
14811.
    function _addNumericSort ( decimalPlace ) {
14812.
        $.each(
14813.
            {
14814.
                // Plain numbers
14815.
                "num": function ( d ) {
14816.
                    return __numericReplace( d, decimalPlace );
14817.
                },
14818.
    
14819.
                // Formatted numbers
14820.
                "num-fmt": function ( d ) {
14821.
                    return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14822.
                },
14823.
    
14824.
                // HTML numeric
14825.
                "html-num": function ( d ) {
14826.
                    return __numericReplace( d, decimalPlace, _re_html );
14827.
                },
14828.
    
14829.
                // HTML numeric, formatted
14830.
                "html-num-fmt": function ( d ) {
14831.
                    return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14832.
                }
14833.
            },
14834.
            function ( key, fn ) {
14835.
                // Add the ordering method
14836.
                _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14837.
    
14838.
                // For HTML types add a search formatter that will strip the HTML
14839.
                if ( key.match(/^html\-/) ) {
14840.
                    _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14841.
                }
14842.
            }
14843.
        );
14844.
    }
14845.
    
14846.
    
14847.
    // Default sort methods
14848.
    $.extend( _ext.type.order, {
14849.
        // Dates
14850.
        "date-pre": function ( d ) {
14851.
            var ts = Date.parse( d );
14852.
            return isNaN(ts) ? -Infinity : ts;
14853.
        },
14854.
    
14855.
        // html
14856.
        "html-pre": function ( a ) {
14857.
            return _empty(a) ?
14858.
                '' :
14859.
                a.replace ?
14860.
                    a.replace( /<.*?>/g, "" ).toLowerCase() :
14861.
                    a+'';
14862.
        },
14863.
    
14864.
        // string
14865.
        "string-pre": function ( a ) {
14866.
            // This is a little complex, but faster than always calling toString,
14867.
            // http://jsperf.com/tostring-v-check
14868.
            return _empty(a) ?
14869.
                '' :
14870.
                typeof a === 'string' ?
14871.
                    a.toLowerCase() :
14872.
                    ! a.toString ?
14873.
                        '' :
14874.
                        a.toString();
14875.
        },
14876.
    
14877.
        // string-asc and -desc are retained only for compatibility with the old
14878.
        // sort methods
14879.
        "string-asc": function ( x, y ) {
14880.
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14881.
        },
14882.
    
14883.
        "string-desc": function ( x, y ) {
14884.
            return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14885.
        }
14886.
    } );
14887.
    
14888.
    
14889.
    // Numeric sorting types - order doesn't matter here
14890.
    _addNumericSort( '' );
14891.
    
14892.
    
14893.
    $.extend( true, DataTable.ext.renderer, {
14894.
        header: {
14895.
            _: function ( settings, cell, column, classes ) {
14896.
                // No additional mark-up required
14897.
                // Attach a sort listener to update on sort - note that using the
14898.
                // `DT` namespace will allow the event to be removed automatically
14899.
                // on destroy, while the `dt` namespaced event is the one we are
14900.
                // listening for
14901.
                $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14902.
                    if ( settings !== ctx ) { // need to check this this is the host
14903.
                        return;               // table, not a nested one
14904.
                    }
14905.
    
14906.
                    var colIdx = column.idx;
14907.
    
14908.
                    cell
14909.
                        .removeClass(
14910.
                            column.sSortingClass +' '+
14911.
                            classes.sSortAsc +' '+
14912.
                            classes.sSortDesc
14913.
                        )
14914.
                        .addClass( columns[ colIdx ] == 'asc' ?
14915.
                            classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14916.
                                classes.sSortDesc :
14917.
                                column.sSortingClass
14918.
                        );
14919.
                } );
14920.
            },
14921.
    
14922.
            jqueryui: function ( settings, cell, column, classes ) {
14923.
                $('<div/>')
14924.
                    .addClass( classes.sSortJUIWrapper )
14925.
                    .append( cell.contents() )
14926.
                    .append( $('<span/>')
14927.
                        .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14928.
                    )
14929.
                    .appendTo( cell );
14930.
    
14931.
                // Attach a sort listener to update on sort
14932.
                $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14933.
                    if ( settings !== ctx ) {
14934.
                        return;
14935.
                    }
14936.
    
14937.
                    var colIdx = column.idx;
14938.
    
14939.
                    cell
14940.
                        .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14941.
                        .addClass( columns[ colIdx ] == 'asc' ?
14942.
                            classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14943.
                                classes.sSortDesc :
14944.
                                column.sSortingClass
14945.
                        );
14946.
    
14947.
                    cell
14948.
                        .find( 'span.'+classes.sSortIcon )
14949.
                        .removeClass(
14950.
                            classes.sSortJUIAsc +" "+
14951.
                            classes.sSortJUIDesc +" "+
14952.
                            classes.sSortJUI +" "+
14953.
                            classes.sSortJUIAscAllowed +" "+
14954.
                            classes.sSortJUIDescAllowed
14955.
                        )
14956.
                        .addClass( columns[ colIdx ] == 'asc' ?
14957.
                            classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14958.
                                classes.sSortJUIDesc :
14959.
                                column.sSortingClassJUI
14960.
                        );
14961.
                } );
14962.
            }
14963.
        }
14964.
    } );
14965.
    
14966.
    /*
14967.
     * Public helper functions. These aren't used internally by DataTables, or
14968.
     * called by any of the options passed into DataTables, but they can be used
14969.
     * externally by developers working with DataTables. They are helper functions
14970.
     * to make working with DataTables a little bit easier.
14971.
     */
14972.
    
14973.
    var __htmlEscapeEntities = function ( d ) {
14974.
        return typeof d === 'string' ?
14975.
            d
14976.
                .replace(/&/g, '&amp;')
14977.
                .replace(/</g, '&lt;')
14978.
                .replace(/>/g, '&gt;')
14979.
                .replace(/"/g, '&quot;') :
14980.
            d;
14981.
    };
14982.
    
14983.
    /**
14984.
     * Helpers for `columns.render`.
14985.
     *
14986.
     * The options defined here can be used with the `columns.render` initialisation
14987.
     * option to provide a display renderer. The following functions are defined:
14988.
     *
14989.
     * * `number` - Will format numeric data (defined by `columns.data`) for
14990.
     *   display, retaining the original unformatted data for sorting and filtering.
14991.
     *   It takes 5 parameters:
14992.
     *   * `string` - Thousands grouping separator
14993.
     *   * `string` - Decimal point indicator
14994.
     *   * `integer` - Number of decimal points to show
14995.
     *   * `string` (optional) - Prefix.
14996.
     *   * `string` (optional) - Postfix (/suffix).
14997.
     * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
14998.
     *   parameters.
14999.
     *
15000.
     * @example
15001.
     *   // Column definition using the number renderer
15002.
     *   {
15003.
     *     data: "salary",
15004.
     *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
15005.
     *   }
15006.
     *
15007.
     * @namespace
15008.
     */
15009.
    DataTable.render = {
15010.
        number: function ( thousands, decimal, precision, prefix, postfix ) {
15011.
            return {
15012.
                display: function ( d ) {
15013.
                    if ( typeof d !== 'number' && typeof d !== 'string' ) {
15014.
                        return d;
15015.
                    }
15016.
    
15017.
                    var negative = d < 0 ? '-' : '';
15018.
                    var flo = parseFloat( d );
15019.
    
15020.
                    // If NaN then there isn't much formatting that we can do - just
15021.
                    // return immediately, escaping any HTML (this was supposed to
15022.
                    // be a number after all)
15023.
                    if ( isNaN( flo ) ) {
15024.
                        return __htmlEscapeEntities( d );
15025.
                    }
15026.
    
15027.
                    flo = flo.toFixed( precision );
15028.
                    d = Math.abs( flo );
15029.
    
15030.
                    var intPart = parseInt( d, 10 );
15031.
                    var floatPart = precision ?
15032.
                        decimal+(d - intPart).toFixed( precision ).substring( 2 ):
15033.
                        '';
15034.
    
15035.
                    return negative + (prefix||'') +
15036.
                        intPart.toString().replace(
15037.
                            /\B(?=(\d{3})+(?!\d))/g, thousands
15038.
                        ) +
15039.
                        floatPart +
15040.
                        (postfix||'');
15041.
                }
15042.
            };
15043.
        },
15044.
    
15045.
        text: function () {
15046.
            return {
15047.
                display: __htmlEscapeEntities,
15048.
                filter: __htmlEscapeEntities
15049.
            };
15050.
        }
15051.
    };
15052.
    
15053.
    
15054.
    /*
15055.
     * This is really a good bit rubbish this method of exposing the internal methods
15056.
     * publicly... - To be fixed in 2.0 using methods on the prototype
15057.
     */
15058.
    
15059.
    
15060.
    /**
15061.
     * Create a wrapper function for exporting an internal functions to an external API.
15062.
     *  @param {string} fn API function name
15063.
     *  @returns {function} wrapped function
15064.
     *  @memberof DataTable#internal
15065.
     */
15066.
    function _fnExternApiFunc (fn)
15067.
    {
15068.
        return function() {
15069.
            var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
15070.
                Array.prototype.slice.call(arguments)
15071.
            );
15072.
            return DataTable.ext.internal[fn].apply( this, args );
15073.
        };
15074.
    }
15075.
    
15076.
    
15077.
    /**
15078.
     * Reference to internal functions for use by plug-in developers. Note that
15079.
     * these methods are references to internal functions and are considered to be
15080.
     * private. If you use these methods, be aware that they are liable to change
15081.
     * between versions.
15082.
     *  @namespace
15083.
     */
15084.
    $.extend( DataTable.ext.internal, {
15085.
        _fnExternApiFunc: _fnExternApiFunc,
15086.
        _fnBuildAjax: _fnBuildAjax,
15087.
        _fnAjaxUpdate: _fnAjaxUpdate,
15088.
        _fnAjaxParameters: _fnAjaxParameters,
15089.
        _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
15090.
        _fnAjaxDataSrc: _fnAjaxDataSrc,
15091.
        _fnAddColumn: _fnAddColumn,
15092.
        _fnColumnOptions: _fnColumnOptions,
15093.
        _fnAdjustColumnSizing: _fnAdjustColumnSizing,
15094.
        _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
15095.
        _fnColumnIndexToVisible: _fnColumnIndexToVisible,
15096.
        _fnVisbleColumns: _fnVisbleColumns,
15097.
        _fnGetColumns: _fnGetColumns,
15098.
        _fnColumnTypes: _fnColumnTypes,
15099.
        _fnApplyColumnDefs: _fnApplyColumnDefs,
15100.
        _fnHungarianMap: _fnHungarianMap,
15101.
        _fnCamelToHungarian: _fnCamelToHungarian,
15102.
        _fnLanguageCompat: _fnLanguageCompat,
15103.
        _fnBrowserDetect: _fnBrowserDetect,
15104.
        _fnAddData: _fnAddData,
15105.
        _fnAddTr: _fnAddTr,
15106.
        _fnNodeToDataIndex: _fnNodeToDataIndex,
15107.
        _fnNodeToColumnIndex: _fnNodeToColumnIndex,
15108.
        _fnGetCellData: _fnGetCellData,
15109.
        _fnSetCellData: _fnSetCellData,
15110.
        _fnSplitObjNotation: _fnSplitObjNotation,
15111.
        _fnGetObjectDataFn: _fnGetObjectDataFn,
15112.
        _fnSetObjectDataFn: _fnSetObjectDataFn,
15113.
        _fnGetDataMaster: _fnGetDataMaster,
15114.
        _fnClearTable: _fnClearTable,
15115.
        _fnDeleteIndex: _fnDeleteIndex,
15116.
        _fnInvalidate: _fnInvalidate,
15117.
        _fnGetRowElements: _fnGetRowElements,
15118.
        _fnCreateTr: _fnCreateTr,
15119.
        _fnBuildHead: _fnBuildHead,
15120.
        _fnDrawHead: _fnDrawHead,
15121.
        _fnDraw: _fnDraw,
15122.
        _fnReDraw: _fnReDraw,
15123.
        _fnAddOptionsHtml: _fnAddOptionsHtml,
15124.
        _fnDetectHeader: _fnDetectHeader,
15125.
        _fnGetUniqueThs: _fnGetUniqueThs,
15126.
        _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
15127.
        _fnFilterComplete: _fnFilterComplete,
15128.
        _fnFilterCustom: _fnFilterCustom,
15129.
        _fnFilterColumn: _fnFilterColumn,
15130.
        _fnFilter: _fnFilter,
15131.
        _fnFilterCreateSearch: _fnFilterCreateSearch,
15132.
        _fnEscapeRegex: _fnEscapeRegex,
15133.
        _fnFilterData: _fnFilterData,
15134.
        _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
15135.
        _fnUpdateInfo: _fnUpdateInfo,
15136.
        _fnInfoMacros: _fnInfoMacros,
15137.
        _fnInitialise: _fnInitialise,
15138.
        _fnInitComplete: _fnInitComplete,
15139.
        _fnLengthChange: _fnLengthChange,
15140.
        _fnFeatureHtmlLength: _fnFeatureHtmlLength,
15141.
        _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
15142.
        _fnPageChange: _fnPageChange,
15143.
        _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
15144.
        _fnProcessingDisplay: _fnProcessingDisplay,
15145.
        _fnFeatureHtmlTable: _fnFeatureHtmlTable,
15146.
        _fnScrollDraw: _fnScrollDraw,
15147.
        _fnApplyToChildren: _fnApplyToChildren,
15148.
        _fnCalculateColumnWidths: _fnCalculateColumnWidths,
15149.
        _fnThrottle: _fnThrottle,
15150.
        _fnConvertToWidth: _fnConvertToWidth,
15151.
        _fnGetWidestNode: _fnGetWidestNode,
15152.
        _fnGetMaxLenString: _fnGetMaxLenString,
15153.
        _fnStringToCss: _fnStringToCss,
15154.
        _fnSortFlatten: _fnSortFlatten,
15155.
        _fnSort: _fnSort,
15156.
        _fnSortAria: _fnSortAria,
15157.
        _fnSortListener: _fnSortListener,
15158.
        _fnSortAttachListener: _fnSortAttachListener,
15159.
        _fnSortingClasses: _fnSortingClasses,
15160.
        _fnSortData: _fnSortData,
15161.
        _fnSaveState: _fnSaveState,
15162.
        _fnLoadState: _fnLoadState,
15163.
        _fnSettingsFromNode: _fnSettingsFromNode,
15164.
        _fnLog: _fnLog,
15165.
        _fnMap: _fnMap,
15166.
        _fnBindAction: _fnBindAction,
15167.
        _fnCallbackReg: _fnCallbackReg,
15168.
        _fnCallbackFire: _fnCallbackFire,
15169.
        _fnLengthOverflow: _fnLengthOverflow,
15170.
        _fnRenderer: _fnRenderer,
15171.
        _fnDataSource: _fnDataSource,
15172.
        _fnRowAttributes: _fnRowAttributes,
15173.
        _fnExtend: _fnExtend,
15174.
        _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
15175.
                                        // in 1.10, so this dead-end function is
15176.
                                        // added to prevent errors
15177.
    } );
15178.
    
15179.
 
15180.
    // jQuery access
15181.
    $.fn.dataTable = DataTable;
15182.
 
15183.
    // Provide access to the host jQuery object (circular reference)
15184.
    DataTable.$ = $;
15185.
 
15186.
    // Legacy aliases
15187.
    $.fn.dataTableSettings = DataTable.settings;
15188.
    $.fn.dataTableExt = DataTable.ext;
15189.
 
15190.
    // With a capital `D` we return a DataTables API instance rather than a
15191.
    // jQuery object
15192.
    $.fn.DataTable = function ( opts ) {
15193.
        return $(this).dataTable( opts ).api();
15194.
    };
15195.
 
15196.
    // All properties that are available to $.fn.dataTable should also be
15197.
    // available on $.fn.DataTable
15198.
    $.each( DataTable, function ( prop, val ) {
15199.
        $.fn.DataTable[ prop ] = val;
15200.
    } );
15201.
 
15202.
 
15203.
    // Information about events fired by DataTables - for documentation.
15204.
    /**
15205.
     * Draw event, fired whenever the table is redrawn on the page, at the same
15206.
     * point as fnDrawCallback. This may be useful for binding events or
15207.
     * performing calculations when the table is altered at all.
15208.
     *  @name DataTable#draw.dt
15209.
     *  @event
15210.
     *  @param {event} e jQuery event object
15211.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15212.
     */
15213.
 
15214.
    /**
15215.
     * Search event, fired when the searching applied to the table (using the
15216.
     * built-in global search, or column filters) is altered.
15217.
     *  @name DataTable#search.dt
15218.
     *  @event
15219.
     *  @param {event} e jQuery event object
15220.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15221.
     */
15222.
 
15223.
    /**
15224.
     * Page change event, fired when the paging of the table is altered.
15225.
     *  @name DataTable#page.dt
15226.
     *  @event
15227.
     *  @param {event} e jQuery event object
15228.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15229.
     */
15230.
 
15231.
    /**
15232.
     * Order event, fired when the ordering applied to the table is altered.
15233.
     *  @name DataTable#order.dt
15234.
     *  @event
15235.
     *  @param {event} e jQuery event object
15236.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15237.
     */
15238.
 
15239.
    /**
15240.
     * DataTables initialisation complete event, fired when the table is fully
15241.
     * drawn, including Ajax data loaded, if Ajax data is required.
15242.
     *  @name DataTable#init.dt
15243.
     *  @event
15244.
     *  @param {event} e jQuery event object
15245.
     *  @param {object} oSettings DataTables settings object
15246.
     *  @param {object} json The JSON object request from the server - only
15247.
     *    present if client-side Ajax sourced data is used</li></ol>
15248.
     */
15249.
 
15250.
    /**
15251.
     * State save event, fired when the table has changed state a new state save
15252.
     * is required. This event allows modification of the state saving object
15253.
     * prior to actually doing the save, including addition or other state
15254.
     * properties (for plug-ins) or modification of a DataTables core property.
15255.
     *  @name DataTable#stateSaveParams.dt
15256.
     *  @event
15257.
     *  @param {event} e jQuery event object
15258.
     *  @param {object} oSettings DataTables settings object
15259.
     *  @param {object} json The state information to be saved
15260.
     */
15261.
 
15262.
    /**
15263.
     * State load event, fired when the table is loading state from the stored
15264.
     * data, but prior to the settings object being modified by the saved state
15265.
     * - allowing modification of the saved state is required or loading of
15266.
     * state for a plug-in.
15267.
     *  @name DataTable#stateLoadParams.dt
15268.
     *  @event
15269.
     *  @param {event} e jQuery event object
15270.
     *  @param {object} oSettings DataTables settings object
15271.
     *  @param {object} json The saved state information
15272.
     */
15273.
 
15274.
    /**
15275.
     * State loaded event, fired when state has been loaded from stored data and
15276.
     * the settings object has been modified by the loaded data.
15277.
     *  @name DataTable#stateLoaded.dt
15278.
     *  @event
15279.
     *  @param {event} e jQuery event object
15280.
     *  @param {object} oSettings DataTables settings object
15281.
     *  @param {object} json The saved state information
15282.
     */
15283.
 
15284.
    /**
15285.
     * Processing event, fired when DataTables is doing some kind of processing
15286.
     * (be it, order, search or anything else). It can be used to indicate to
15287.
     * the end user that there is something happening, or that something has
15288.
     * finished.
15289.
     *  @name DataTable#processing.dt
15290.
     *  @event
15291.
     *  @param {event} e jQuery event object
15292.
     *  @param {object} oSettings DataTables settings object
15293.
     *  @param {boolean} bShow Flag for if DataTables is doing processing or not
15294.
     */
15295.
 
15296.
    /**
15297.
     * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15298.
     * request to made to the server for new data. This event is called before
15299.
     * DataTables processed the returned data, so it can also be used to pre-
15300.
     * process the data returned from the server, if needed.
15301.
     *
15302.
     * Note that this trigger is called in `fnServerData`, if you override
15303.
     * `fnServerData` and which to use this event, you need to trigger it in you
15304.
     * success function.
15305.
     *  @name DataTable#xhr.dt
15306.
     *  @event
15307.
     *  @param {event} e jQuery event object
15308.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15309.
     *  @param {object} json JSON returned from the server
15310.
     *
15311.
     *  @example
15312.
     *     // Use a custom property returned from the server in another DOM element
15313.
     *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15314.
     *       $('#status').html( json.status );
15315.
     *     } );
15316.
     *
15317.
     *  @example
15318.
     *     // Pre-process the data returned from the server
15319.
     *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15320.
     *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15321.
     *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15322.
     *       }
15323.
     *       // Note no return - manipulate the data directly in the JSON object.
15324.
     *     } );
15325.
     */
15326.
 
15327.
    /**
15328.
     * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15329.
     * or passing the bDestroy:true parameter in the initialisation object. This
15330.
     * can be used to remove bound events, added DOM nodes, etc.
15331.
     *  @name DataTable#destroy.dt
15332.
     *  @event
15333.
     *  @param {event} e jQuery event object
15334.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15335.
     */
15336.
 
15337.
    /**
15338.
     * Page length change event, fired when number of records to show on each
15339.
     * page (the length) is changed.
15340.
     *  @name DataTable#length.dt
15341.
     *  @event
15342.
     *  @param {event} e jQuery event object
15343.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15344.
     *  @param {integer} len New length
15345.
     */
15346.
 
15347.
    /**
15348.
     * Column sizing has changed.
15349.
     *  @name DataTable#column-sizing.dt
15350.
     *  @event
15351.
     *  @param {event} e jQuery event object
15352.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15353.
     */
15354.
 
15355.
    /**
15356.
     * Column visibility has changed.
15357.
     *  @name DataTable#column-visibility.dt
15358.
     *  @event
15359.
     *  @param {event} e jQuery event object
15360.
     *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15361.
     *  @param {int} column Column index
15362.
     *  @param {bool} vis `false` if column now hidden, or `true` if visible
15363.
     */
15364.
 
15365.
    return $.fn.dataTable;
15366.
}));
15367.
 
15368.
 
15369.