1D array of data - add a single row with the data provided
\n\t *
2D array of arrays - add multiple rows in a single call
\n\t *
object - data object when using mData
\n\t *
array of objects - multiple data objects when using mData
\n\t *
\n\t * @param {bool} [redraw=true] redraw the table or not\n\t * @returns {array} An array of integers, representing the list of indexes in\n\t * aoData ({@link DataTable.models.oSettings}) that have been added to\n\t * the table.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * // Global var for counter\n\t * var giCount = 2;\n\t *\n\t * $(document).ready(function() {\n\t * $('#example').dataTable();\n\t * } );\n\t *\n\t * function fnClickAddRow() {\n\t * $('#example').dataTable().fnAddData( [\n\t * giCount+\".1\",\n\t * giCount+\".2\",\n\t * giCount+\".3\",\n\t * giCount+\".4\" ]\n\t * );\n\t *\n\t * giCount++;\n\t * }\n\t */\n\tthis.fnAddData = function( data, redraw )\n\t{\n\t\tvar api = this.api( true );\n\t\n\t\t/* Check if we want to add multiple rows or not */\n\t\tvar rows = Array.isArray(data) && ( Array.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\n\t\t\tapi.rows.add( data ) :\n\t\t\tapi.row.add( data );\n\t\n\t\tif ( redraw === undefined || redraw ) {\n\t\t\tapi.draw();\n\t\t}\n\t\n\t\treturn rows.flatten().toArray();\n\t};\n\t\n\t\n\t/**\n\t * This function will make DataTables recalculate the column sizes, based on the data\n\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\n\t * through the sWidth parameter). This can be useful when the width of the table's\n\t * parent element changes (for example a window resize).\n\t * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable( {\n\t * \"sScrollY\": \"200px\",\n\t * \"bPaginate\": false\n\t * } );\n\t *\n\t * $(window).on('resize', function () {\n\t * oTable.fnAdjustColumnSizing();\n\t * } );\n\t * } );\n\t */\n\tthis.fnAdjustColumnSizing = function ( bRedraw )\n\t{\n\t\tvar api = this.api( true ).columns.adjust();\n\t\tvar settings = api.settings()[0];\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\tapi.draw( false );\n\t\t}\n\t\telse if ( scroll.sX !== \"\" || scroll.sY !== \"\" ) {\n\t\t\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\n\t\t\t_fnScrollDraw( settings );\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Quickly and simply clear a table\n\t * @param {bool} [bRedraw=true] redraw the table or not\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\n\t * oTable.fnClearTable();\n\t * } );\n\t */\n\tthis.fnClearTable = function( bRedraw )\n\t{\n\t\tvar api = this.api( true ).clear();\n\t\n\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\tapi.draw();\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * The exact opposite of 'opening' a row, this function will close any rows which\n\t * are currently 'open'.\n\t * @param {node} nTr the table row to 'close'\n\t * @returns {int} 0 on success, or 1 if failed (can't find the row)\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable;\n\t *\n\t * // 'open' an information row when a row is clicked on\n\t * $('#example tbody tr').click( function () {\n\t * if ( oTable.fnIsOpen(this) ) {\n\t * oTable.fnClose( this );\n\t * } else {\n\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t * }\n\t * } );\n\t *\n\t * oTable = $('#example').dataTable();\n\t * } );\n\t */\n\tthis.fnClose = function( nTr )\n\t{\n\t\tthis.api( true ).row( nTr ).child.hide();\n\t};\n\t\n\t\n\t/**\n\t * Remove a row for the table\n\t * @param {mixed} target The index of the row from aoData to be deleted, or\n\t * the TR element you want to delete\n\t * @param {function|null} [callBack] Callback function\n\t * @param {bool} [redraw=true] Redraw the table or not\n\t * @returns {array} The row that was deleted\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Immediately remove the first row\n\t * oTable.fnDeleteRow( 0 );\n\t * } );\n\t */\n\tthis.fnDeleteRow = function( target, callback, redraw )\n\t{\n\t\tvar api = this.api( true );\n\t\tvar rows = api.rows( target );\n\t\tvar settings = rows.settings()[0];\n\t\tvar data = settings.aoData[ rows[0][0] ];\n\t\n\t\trows.remove();\n\t\n\t\tif ( callback ) {\n\t\t\tcallback.call( this, settings, data );\n\t\t}\n\t\n\t\tif ( redraw === undefined || redraw ) {\n\t\t\tapi.draw();\n\t\t}\n\t\n\t\treturn data;\n\t};\n\t\n\t\n\t/**\n\t * Restore the table to it's original state in the DOM by removing all of DataTables\n\t * enhancements, alterations to the DOM structure of the table and event listeners.\n\t * @param {boolean} [remove=false] Completely remove the table from the DOM\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * // This example is fairly pointless in reality, but shows how fnDestroy can be used\n\t * var oTable = $('#example').dataTable();\n\t * oTable.fnDestroy();\n\t * } );\n\t */\n\tthis.fnDestroy = function ( remove )\n\t{\n\t\tthis.api( true ).destroy( remove );\n\t};\n\t\n\t\n\t/**\n\t * Redraw the table\n\t * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\n\t * oTable.fnDraw();\n\t * } );\n\t */\n\tthis.fnDraw = function( complete )\n\t{\n\t\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\n\t\t// into account the new data, but can hold position.\n\t\tthis.api( true ).draw( complete );\n\t};\n\t\n\t\n\t/**\n\t * Filter the input based on data\n\t * @param {string} sInput String to filter the table on\n\t * @param {int|null} [iColumn] Column to limit filtering to\n\t * @param {bool} [bRegex=false] Treat as regular expression or not\n\t * @param {bool} [bSmart=true] Perform smart filtering or not\n\t * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\n\t * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Sometime later - filter...\n\t * oTable.fnFilter( 'test string' );\n\t * } );\n\t */\n\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\n\t{\n\t\tvar api = this.api( true );\n\t\n\t\tif ( iColumn === null || iColumn === undefined ) {\n\t\t\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t}\n\t\telse {\n\t\t\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t}\n\t\n\t\tapi.draw();\n\t};\n\t\n\t\n\t/**\n\t * Get the data for the whole table, an individual row or an individual cell based on the\n\t * provided parameters.\n\t * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\n\t * a TR node then the data source for the whole row will be returned. If given as a\n\t * TD/TH cell node then iCol will be automatically calculated and the data for the\n\t * cell returned. If given as an integer, then this is treated as the aoData internal\n\t * data index for the row (see fnGetPosition) and the data for that row used.\n\t * @param {int} [col] Optional column index that you want the data of.\n\t * @returns {array|object|string} If mRow is undefined, then the data for all rows is\n\t * returned. If mRow is defined, just data for that row, and is iCol is\n\t * defined, only data for the designated cell is returned.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * // Row data\n\t * $(document).ready(function() {\n\t * oTable = $('#example').dataTable();\n\t *\n\t * oTable.$('tr').click( function () {\n\t * var data = oTable.fnGetData( this );\n\t * // ... do something with the array / object of data for the row\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Individual cell data\n\t * $(document).ready(function() {\n\t * oTable = $('#example').dataTable();\n\t *\n\t * oTable.$('td').click( function () {\n\t * var sData = oTable.fnGetData( this );\n\t * alert( 'The cell clicked on had the value of '+sData );\n\t * } );\n\t * } );\n\t */\n\tthis.fnGetData = function( src, col )\n\t{\n\t\tvar api = this.api( true );\n\t\n\t\tif ( src !== undefined ) {\n\t\t\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\n\t\n\t\t\treturn col !== undefined || type == 'td' || type == 'th' ?\n\t\t\t\tapi.cell( src, col ).data() :\n\t\t\t\tapi.row( src ).data() || null;\n\t\t}\n\t\n\t\treturn api.data().toArray();\n\t};\n\t\n\t\n\t/**\n\t * Get an array of the TR nodes that are used in the table's body. Note that you will\n\t * typically want to use the '$' API method in preference to this as it is more\n\t * flexible.\n\t * @param {int} [iRow] Optional row index for the TR element you want\n\t * @returns {array|node} If iRow is undefined, returns an array of all TR elements\n\t * in the table's body, or iRow is defined, just the TR element requested.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Get the nodes from the table\n\t * var nNodes = oTable.fnGetNodes( );\n\t * } );\n\t */\n\tthis.fnGetNodes = function( iRow )\n\t{\n\t\tvar api = this.api( true );\n\t\n\t\treturn iRow !== undefined ?\n\t\t\tapi.row( iRow ).node() :\n\t\t\tapi.rows().nodes().flatten().toArray();\n\t};\n\t\n\t\n\t/**\n\t * Get the array indexes of a particular cell from it's DOM element\n\t * and column index including hidden columns\n\t * @param {node} node this can either be a TR, TD or TH in the table's body\n\t * @returns {int} If nNode is given as a TR, then a single index is returned, or\n\t * if given as a cell, an array of [row index, column index (visible),\n\t * column index (all)] is given.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * $('#example tbody td').click( function () {\n\t * // Get the position of the current data from the node\n\t * var aPos = oTable.fnGetPosition( this );\n\t *\n\t * // Get the data array for this row\n\t * var aData = oTable.fnGetData( aPos[0] );\n\t *\n\t * // Update the data array and return the value\n\t * aData[ aPos[1] ] = 'clicked';\n\t * this.innerHTML = 'clicked';\n\t * } );\n\t *\n\t * // Init DataTables\n\t * oTable = $('#example').dataTable();\n\t * } );\n\t */\n\tthis.fnGetPosition = function( node )\n\t{\n\t\tvar api = this.api( true );\n\t\tvar nodeName = node.nodeName.toUpperCase();\n\t\n\t\tif ( nodeName == 'TR' ) {\n\t\t\treturn api.row( node ).index();\n\t\t}\n\t\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\n\t\t\tvar cell = api.cell( node ).index();\n\t\n\t\t\treturn [\n\t\t\t\tcell.row,\n\t\t\t\tcell.columnVisible,\n\t\t\t\tcell.column\n\t\t\t];\n\t\t}\n\t\treturn null;\n\t};\n\t\n\t\n\t/**\n\t * Check to see if a row is 'open' or not.\n\t * @param {node} nTr the table row to check\n\t * @returns {boolean} true if the row is currently open, false otherwise\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable;\n\t *\n\t * // 'open' an information row when a row is clicked on\n\t * $('#example tbody tr').click( function () {\n\t * if ( oTable.fnIsOpen(this) ) {\n\t * oTable.fnClose( this );\n\t * } else {\n\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t * }\n\t * } );\n\t *\n\t * oTable = $('#example').dataTable();\n\t * } );\n\t */\n\tthis.fnIsOpen = function( nTr )\n\t{\n\t\treturn this.api( true ).row( nTr ).child.isShown();\n\t};\n\t\n\t\n\t/**\n\t * This function will place a new row directly after a row which is currently\n\t * on display on the page, with the HTML contents that is passed into the\n\t * function. This can be used, for example, to ask for confirmation that a\n\t * particular record should be deleted.\n\t * @param {node} nTr The table row to 'open'\n\t * @param {string|node|jQuery} mHtml The HTML to put into the row\n\t * @param {string} sClass Class to give the new TD cell\n\t * @returns {node} The row opened. Note that if the table row passed in as the\n\t * first parameter, is not found in the table, this method will silently\n\t * return.\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable;\n\t *\n\t * // 'open' an information row when a row is clicked on\n\t * $('#example tbody tr').click( function () {\n\t * if ( oTable.fnIsOpen(this) ) {\n\t * oTable.fnClose( this );\n\t * } else {\n\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t * }\n\t * } );\n\t *\n\t * oTable = $('#example').dataTable();\n\t * } );\n\t */\n\tthis.fnOpen = function( nTr, mHtml, sClass )\n\t{\n\t\treturn this.api( true )\n\t\t\t.row( nTr )\n\t\t\t.child( mHtml, sClass )\n\t\t\t.show()\n\t\t\t.child()[0];\n\t};\n\t\n\t\n\t/**\n\t * Change the pagination - provides the internal logic for pagination in a simple API\n\t * function. With this function you can have a DataTables table go to the next,\n\t * previous, first or last pages.\n\t * @param {string|int} mAction Paging action to take: \"first\", \"previous\", \"next\" or \"last\"\n\t * or page number to jump to (integer), note that page 0 is the first page.\n\t * @param {bool} [bRedraw=true] Redraw the table or not\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t * oTable.fnPageChange( 'next' );\n\t * } );\n\t */\n\tthis.fnPageChange = function ( mAction, bRedraw )\n\t{\n\t\tvar api = this.api( true ).page( mAction );\n\t\n\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\tapi.draw(false);\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Show a particular column\n\t * @param {int} iCol The column whose display should be changed\n\t * @param {bool} bShow Show (true) or hide (false) the column\n\t * @param {bool} [bRedraw=true] Redraw the table or not\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Hide the second column after initialisation\n\t * oTable.fnSetColumnVis( 1, false );\n\t * } );\n\t */\n\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\n\t{\n\t\tvar api = this.api( true ).column( iCol ).visible( bShow );\n\t\n\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\tapi.columns.adjust().draw();\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Get the settings for a particular table for external manipulation\n\t * @returns {object} DataTables settings object. See\n\t * {@link DataTable.models.oSettings}\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t * var oSettings = oTable.fnSettings();\n\t *\n\t * // Show an example parameter from the settings\n\t * alert( oSettings._iDisplayStart );\n\t * } );\n\t */\n\tthis.fnSettings = function()\n\t{\n\t\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\n\t};\n\t\n\t\n\t/**\n\t * Sort the table by a particular column\n\t * @param {int} iCol the data index to sort on. Note that this will not match the\n\t * 'display index' if you have hidden data entries\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Sort immediately with columns 0 and 1\n\t * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\n\t * } );\n\t */\n\tthis.fnSort = function( aaSort )\n\t{\n\t\tthis.api( true ).order( aaSort ).draw();\n\t};\n\t\n\t\n\t/**\n\t * Attach a sort listener to an element for a given column\n\t * @param {node} nNode the element to attach the sort listener to\n\t * @param {int} iColumn the column that a click on this node will sort on\n\t * @param {function} [fnCallback] callback function when sort is run\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t *\n\t * // Sort on column 1, when 'sorter' is clicked on\n\t * oTable.fnSortListener( document.getElementById('sorter'), 1 );\n\t * } );\n\t */\n\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\n\t{\n\t\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\n\t};\n\t\n\t\n\t/**\n\t * Update a table cell or row - this method will accept either a single value to\n\t * update the cell with, an array of values with one element for each column or\n\t * an object in the same format as the original data source. The function is\n\t * self-referencing in order to make the multi column updates easier.\n\t * @param {object|array|string} mData Data to update the cell/row with\n\t * @param {node|int} mRow TR element you want to update or the aoData index\n\t * @param {int} [iColumn] The column to update, give as null or undefined to\n\t * update a whole row.\n\t * @param {bool} [bRedraw=true] Redraw the table or not\n\t * @param {bool} [bAction=true] Perform pre-draw actions or not\n\t * @returns {int} 0 on success, 1 on error\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\n\t * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\n\t * } );\n\t */\n\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\n\t{\n\t\tvar api = this.api( true );\n\t\n\t\tif ( iColumn === undefined || iColumn === null ) {\n\t\t\tapi.row( mRow ).data( mData );\n\t\t}\n\t\telse {\n\t\t\tapi.cell( mRow, iColumn ).data( mData );\n\t\t}\n\t\n\t\tif ( bAction === undefined || bAction ) {\n\t\t\tapi.columns.adjust();\n\t\t}\n\t\n\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\tapi.draw();\n\t\t}\n\t\treturn 0;\n\t};\n\t\n\t\n\t/**\n\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\n\t * to ensure compatibility.\n\t * @param {string} sVersion Version string to check for, in the format \"X.Y.Z\". Note that the\n\t * formats \"X\" and \"X.Y\" are also acceptable.\n\t * @returns {boolean} true if this version of DataTables is greater or equal to the required\n\t * version, or false if this version of DataTales is not suitable\n\t * @method\n\t * @dtopt API\n\t * @deprecated Since v1.10\n\t *\n\t * @example\n\t * $(document).ready(function() {\n\t * var oTable = $('#example').dataTable();\n\t * alert( oTable.fnVersionCheck( '1.9.0' ) );\n\t * } );\n\t */\n\tthis.fnVersionCheck = _ext.fnVersionCheck;\n\t\n\n\tvar _that = this;\n\tvar emptyInit = options === undefined;\n\tvar len = this.length;\n\n\tif ( emptyInit ) {\n\t\toptions = {};\n\t}\n\n\tthis.oApi = this.internal = _ext.internal;\n\n\t// Extend with old style plug-in API methods\n\tfor ( var fn in DataTable.ext.internal ) {\n\t\tif ( fn ) {\n\t\t\tthis[fn] = _fnExternApiFunc(fn);\n\t\t}\n\t}\n\n\tthis.each(function() {\n\t\t// For each initialisation we want to give it a clean initialisation\n\t\t// object that can be bashed around\n\t\tvar o = {};\n\t\tvar oInit = len > 1 ? // optimisation for single table case\n\t\t\t_fnExtend( o, options, true ) :\n\t\t\toptions;\n\n\t\t/*global oInit,_that,emptyInit*/\n\t\tvar i=0, iLen, j, jLen, k, kLen;\n\t\tvar sId = this.getAttribute( 'id' );\n\t\tvar bInitHandedOff = false;\n\t\tvar defaults = DataTable.defaults;\n\t\tvar $this = $(this);\n\t\t\n\t\t\n\t\t/* Sanity check */\n\t\tif ( this.nodeName.toLowerCase() != 'table' )\n\t\t{\n\t\t\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t/* Backwards compatibility for the defaults */\n\t\t_fnCompatOpts( defaults );\n\t\t_fnCompatCols( defaults.column );\n\t\t\n\t\t/* Convert the camel-case defaults to Hungarian */\n\t\t_fnCamelToHungarian( defaults, defaults, true );\n\t\t_fnCamelToHungarian( defaults.column, defaults.column, true );\n\t\t\n\t\t/* Setting up the initialisation object */\n\t\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );\n\t\t\n\t\t\n\t\t\n\t\t/* Check to see if we are re-initialising a table */\n\t\tvar allSettings = DataTable.settings;\n\t\tfor ( i=0, iLen=allSettings.length ; i').appendTo($this);\n\t\t\t}\n\t\t\toSettings.nTHead = thead[0];\n\t\t\n\t\t\tvar tbody = $this.children('tbody');\n\t\t\tif ( tbody.length === 0 ) {\n\t\t\t\ttbody = $('').insertAfter(thead);\n\t\t\t}\n\t\t\toSettings.nTBody = tbody[0];\n\t\t\n\t\t\tvar tfoot = $this.children('tfoot');\n\t\t\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") ) {\n\t\t\t\t// If we are a scrolling table, and no footer has been given, then we need to create\n\t\t\t\t// a tfoot element for the caption element to be appended to\n\t\t\t\ttfoot = $('').appendTo($this);\n\t\t\t}\n\t\t\n\t\t\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\n\t\t\t\t$this.addClass( oClasses.sNoFooter );\n\t\t\t}\n\t\t\telse if ( tfoot.length > 0 ) {\n\t\t\t\toSettings.nTFoot = tfoot[0];\n\t\t\t\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\n\t\t\t}\n\t\t\n\t\t\t/* Check if there is data passing into the constructor */\n\t\t\tif ( oInit.aaData ) {\n\t\t\t\tfor ( i=0 ; i/g;\n\n// This is not strict ISO8601 - Date.parse() is quite lax, although\n// implementations differ between browsers.\nvar _re_date = /^\\d{2,4}[\\.\\/\\-]\\d{1,2}[\\.\\/\\-]\\d{1,2}([T ]{1}\\d{1,2}[:\\.]\\d{2}([\\.:]\\d{2})?)?$/;\n\n// Escape regular expression special characters\nvar _re_escape_regex = new RegExp( '(\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\', '$', '^', '-' ].join('|\\\\') + ')', 'g' );\n\n// https://en.wikipedia.org/wiki/Foreign_exchange_market\n// - \\u20BD - Russian ruble.\n// - \\u20a9 - South Korean Won\n// - \\u20BA - Turkish Lira\n// - \\u20B9 - Indian Rupee\n// - R - Brazil (R$) and South Africa\n// - fr - Swiss Franc\n// - kr - Swedish krona, Norwegian krone and Danish krone\n// - \\u2009 is thin space and \\u202F is narrow no-break space, both used in many\n// - Ƀ - Bitcoin\n// - Ξ - Ethereum\n// standards as thousands separators.\nvar _re_formatted_numeric = /['\\u00A0,$£€¥%\\u2009\\u202F\\u20BD\\u20a9\\u20BArfkɃΞ]/gi;\n\n\nvar _empty = function ( d ) {\n\treturn !d || d === true || d === '-' ? true : false;\n};\n\n\nvar _intVal = function ( s ) {\n\tvar integer = parseInt( s, 10 );\n\treturn !isNaN(integer) && isFinite(s) ? integer : null;\n};\n\n// Convert from a formatted number with characters other than `.` as the\n// decimal place, to a Javascript number\nvar _numToDecimal = function ( num, decimalPoint ) {\n\t// Cache created regular expressions for speed as this function is called often\n\tif ( ! _re_dic[ decimalPoint ] ) {\n\t\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\n\t}\n\treturn typeof num === 'string' && decimalPoint !== '.' ?\n\t\tnum.replace( /\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\n\t\tnum;\n};\n\n\nvar _isNumber = function ( d, decimalPoint, formatted ) {\n\tvar type = typeof d;\n\tvar strType = type === 'string';\n\n\tif ( type === 'number' || type === 'bigint') {\n\t\treturn true;\n\t}\n\n\t// If empty return immediately so there must be a number if it is a\n\t// formatted string (this stops the string \"k\", or \"kr\", etc being detected\n\t// as a formatted number for currency\n\tif ( _empty( d ) ) {\n\t\treturn true;\n\t}\n\n\tif ( decimalPoint && strType ) {\n\t\td = _numToDecimal( d, decimalPoint );\n\t}\n\n\tif ( formatted && strType ) {\n\t\td = d.replace( _re_formatted_numeric, '' );\n\t}\n\n\treturn !isNaN( parseFloat(d) ) && isFinite( d );\n};\n\n\n// A string without HTML in it can be considered to be HTML still\nvar _isHtml = function ( d ) {\n\treturn _empty( d ) || typeof d === 'string';\n};\n\n\nvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\n\tif ( _empty( d ) ) {\n\t\treturn true;\n\t}\n\n\tvar html = _isHtml( d );\n\treturn ! html ?\n\t\tnull :\n\t\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\n\t\t\ttrue :\n\t\t\tnull;\n};\n\n\nvar _pluck = function ( a, prop, prop2 ) {\n\tvar out = [];\n\tvar i=0, ien=a.length;\n\n\t// Could have the test in the loop for slightly smaller code, but speed\n\t// is essential here\n\tif ( prop2 !== undefined ) {\n\t\tfor ( ; i')\n\t\t\t.css( {\n\t\t\t\tposition: 'fixed',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: $(window).scrollLeft()*-1, // allow for scrolling\n\t\t\t\theight: 1,\n\t\t\t\twidth: 1,\n\t\t\t\toverflow: 'hidden'\n\t\t\t} )\n\t\t\t.append(\n\t\t\t\t$('')\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: 1,\n\t\t\t\t\t\tleft: 1,\n\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\toverflow: 'scroll'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$('')\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\theight: 10\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.appendTo( 'body' );\n\n\t\tvar outer = n.children();\n\t\tvar inner = outer.children();\n\n\t\t// Numbers below, in order, are:\n\t\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\n\t\t//\n\t\t// IE6 XP: 100 100 100 83\n\t\t// IE7 Vista: 100 100 100 83\n\t\t// IE 8+ Windows: 83 83 100 83\n\t\t// Evergreen Windows: 83 83 100 83\n\t\t// Evergreen Mac with scrollbars: 85 85 100 85\n\t\t// Evergreen Mac without scrollbars: 100 100 100 100\n\n\t\t// Get scrollbar width\n\t\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\n\n\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n\t\t// include the width of the scrollbar, while other browsers ensure the inner\n\t\t// element is contained without forcing scrolling\n\t\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\n\n\t\t// In rtl text layout, some browsers (most, but not all) will place the\n\t\t// scrollbar on the left, rather than the right.\n\t\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\n\n\t\t// IE8- don't provide height and width for getBoundingClientRect\n\t\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\n\n\t\tn.remove();\n\t}\n\n\t$.extend( settings.oBrowser, DataTable.__browser );\n\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\n}\n\n\n/**\n * Array.prototype reduce[Right] method, used for browsers which don't support\n * JS 1.6. Done this way to reduce code size, since we iterate either way\n * @param {object} settings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnReduce ( that, fn, init, start, end, inc )\n{\n\tvar\n\t\ti = start,\n\t\tvalue,\n\t\tisSet = false;\n\n\tif ( init !== undefined ) {\n\t\tvalue = init;\n\t\tisSet = true;\n\t}\n\n\twhile ( i !== end ) {\n\t\tif ( ! that.hasOwnProperty(i) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalue = isSet ?\n\t\t\tfn( value, that[i], i, that ) :\n\t\t\tthat[i];\n\n\t\tisSet = true;\n\t\ti += inc;\n\t}\n\n\treturn value;\n}\n\n/**\n * Add a column to the list used for the table with default values\n * @param {object} oSettings dataTables settings object\n * @param {node} nTh The th element for this column\n * @memberof DataTable#oApi\n */\nfunction _fnAddColumn( oSettings, nTh )\n{\n\t// Add column to aoColumns array\n\tvar oDefaults = DataTable.defaults.column;\n\tvar iCol = oSettings.aoColumns.length;\n\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\n\t\t\"nTh\": nTh ? nTh : document.createElement('th'),\n\t\t\"sTitle\": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',\n\t\t\"aDataSort\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\n\t\t\"mData\": oDefaults.mData ? oDefaults.mData : iCol,\n\t\tidx: iCol\n\t} );\n\toSettings.aoColumns.push( oCol );\n\n\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\n\t// passed into extend can be undefined. This allows the user to give a default\n\t// with only some of the parameters defined, and also not give a default\n\tvar searchCols = oSettings.aoPreSearchCols;\n\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\n\n\t// Use the default column options function to initialise classes etc\n\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\n}\n\n\n/**\n * Apply options for a column\n * @param {object} oSettings dataTables settings object\n * @param {int} iCol column index to consider\n * @param {object} oOptions object with sType, bVisible and bSearchable etc\n * @memberof DataTable#oApi\n */\nfunction _fnColumnOptions( oSettings, iCol, oOptions )\n{\n\tvar oCol = oSettings.aoColumns[ iCol ];\n\tvar oClasses = oSettings.oClasses;\n\tvar th = $(oCol.nTh);\n\n\t// Try to get width information from the DOM. We can't get it from CSS\n\t// as we'd need to parse the CSS stylesheet. `width` option can override\n\tif ( ! oCol.sWidthOrig ) {\n\t\t// Width attribute\n\t\toCol.sWidthOrig = th.attr('width') || null;\n\n\t\t// Style attribute\n\t\tvar t = (th.attr('style') || '').match(/width:\\s*(\\d+[pxem%]+)/);\n\t\tif ( t ) {\n\t\t\toCol.sWidthOrig = t[1];\n\t\t}\n\t}\n\n\t/* User specified column options */\n\tif ( oOptions !== undefined && oOptions !== null )\n\t{\n\t\t// Backwards compatibility\n\t\t_fnCompatCols( oOptions );\n\n\t\t// Map camel case parameters to their Hungarian counterparts\n\t\t_fnCamelToHungarian( DataTable.defaults.column, oOptions, true );\n\n\t\t/* Backwards compatibility for mDataProp */\n\t\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\n\t\t{\n\t\t\toOptions.mData = oOptions.mDataProp;\n\t\t}\n\n\t\tif ( oOptions.sType )\n\t\t{\n\t\t\toCol._sManualType = oOptions.sType;\n\t\t}\n\n\t\t// `class` is a reserved word in Javascript, so we need to provide\n\t\t// the ability to use a valid name for the camel case input\n\t\tif ( oOptions.className && ! oOptions.sClass )\n\t\t{\n\t\t\toOptions.sClass = oOptions.className;\n\t\t}\n\t\tif ( oOptions.sClass ) {\n\t\t\tth.addClass( oOptions.sClass );\n\t\t}\n\n\t\tvar origClass = oCol.sClass;\n\n\t\t$.extend( oCol, oOptions );\n\t\t_fnMap( oCol, oOptions, \"sWidth\", \"sWidthOrig\" );\n\n\t\t// Merge class from previously defined classes with this one, rather than just\n\t\t// overwriting it in the extend above\n\t\tif (origClass !== oCol.sClass) {\n\t\t\toCol.sClass = origClass + ' ' + oCol.sClass;\n\t\t}\n\n\t\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\n\t\t * priority if defined\n\t\t */\n\t\tif ( oOptions.iDataSort !== undefined )\n\t\t{\n\t\t\toCol.aDataSort = [ oOptions.iDataSort ];\n\t\t}\n\t\t_fnMap( oCol, oOptions, \"aDataSort\" );\n\n\t\t// Fall back to the aria-label attribute on the table header if no ariaTitle is\n\t\t// provided.\n\t\tif (! oCol.ariaTitle) {\n\t\t\toCol.ariaTitle = th.attr(\"aria-label\");\n\t\t}\n\t}\n\n\t/* Cache the data get and set functions for speed */\n\tvar mDataSrc = oCol.mData;\n\tvar mData = _fnGetObjectDataFn( mDataSrc );\n\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\n\n\tvar attrTest = function( src ) {\n\t\treturn typeof src === 'string' && src.indexOf('@') !== -1;\n\t};\n\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\n\t\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\n\t);\n\toCol._setter = null;\n\n\toCol.fnGetData = function (rowData, type, meta) {\n\t\tvar innerData = mData( rowData, type, undefined, meta );\n\n\t\treturn mRender && type ?\n\t\t\tmRender( innerData, type, rowData, meta ) :\n\t\t\tinnerData;\n\t};\n\toCol.fnSetData = function ( rowData, val, meta ) {\n\t\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\n\t};\n\n\t// Indicate if DataTables should read DOM data as an object or array\n\t// Used in _fnGetRowElements\n\tif ( typeof mDataSrc !== 'number' && ! oCol._isArrayHost ) {\n\t\toSettings._rowReadObject = true;\n\t}\n\n\t/* Feature sorting overrides column specific when off */\n\tif ( !oSettings.oFeatures.bSort )\n\t{\n\t\toCol.bSortable = false;\n\t\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\n\t}\n\n\t/* Check that the class assignment is correct for sorting */\n\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\n\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\n\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\n\t{\n\t\toCol.sSortingClass = oClasses.sSortableNone;\n\t\toCol.sSortingClassJUI = \"\";\n\t}\n\telse if ( bAsc && !bDesc )\n\t{\n\t\toCol.sSortingClass = oClasses.sSortableAsc;\n\t\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\n\t}\n\telse if ( !bAsc && bDesc )\n\t{\n\t\toCol.sSortingClass = oClasses.sSortableDesc;\n\t\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\n\t}\n\telse\n\t{\n\t\toCol.sSortingClass = oClasses.sSortable;\n\t\toCol.sSortingClassJUI = oClasses.sSortJUI;\n\t}\n}\n\n\n/**\n * Adjust the table column widths for new data. Note: you would probably want to\n * do a redraw after calling this function!\n * @param {object} settings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnAdjustColumnSizing ( settings )\n{\n\t/* Not interested in doing column width calculation if auto-width is disabled */\n\tif ( settings.oFeatures.bAutoWidth !== false )\n\t{\n\t\tvar columns = settings.aoColumns;\n\n\t\t_fnCalculateColumnWidths( settings );\n\t\tfor ( var i=0 , iLen=columns.length ; i=0 ; i-- )\n\t\t{\n\t\t\tdef = aoColDefs[i];\n\n\t\t\t/* Each definition can target multiple columns, as it is an array */\n\t\t\tvar aTargets = def.target !== undefined\n\t\t\t\t? def.target\n\t\t\t\t: def.targets !== undefined\n\t\t\t\t\t? def.targets\n\t\t\t\t\t: def.aTargets;\n\n\t\t\tif ( ! Array.isArray( aTargets ) )\n\t\t\t{\n\t\t\t\taTargets = [ aTargets ];\n\t\t\t}\n\n\t\t\tfor ( j=0, jLen=aTargets.length ; j= 0 )\n\t\t\t\t{\n\t\t\t\t\t/* Add columns that we don't yet know about */\n\t\t\t\t\twhile( columns.length <= aTargets[j] )\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnAddColumn( oSettings );\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Integer, basic index */\n\t\t\t\t\tfn( aTargets[j], def );\n\t\t\t\t}\n\t\t\t\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\n\t\t\t\t{\n\t\t\t\t\t/* Negative integer, right to left column counting */\n\t\t\t\t\tfn( columns.length+aTargets[j], def );\n\t\t\t\t}\n\t\t\t\telse if ( typeof aTargets[j] === 'string' )\n\t\t\t\t{\n\t\t\t\t\t/* Class name matching on TH element */\n\t\t\t\t\tfor ( k=0, kLen=columns.length ; k=0 if successful (index of new aoData entry), -1 if failed\n * @memberof DataTable#oApi\n */\nfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\n{\n\t/* Create the object for storing information about this new row */\n\tvar iRow = oSettings.aoData.length;\n\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\n\t\tsrc: nTr ? 'dom' : 'data',\n\t\tidx: iRow\n\t} );\n\n\toData._aData = aDataIn;\n\toSettings.aoData.push( oData );\n\n\t/* Create the cells */\n\tvar nTd, sThisType;\n\tvar columns = oSettings.aoColumns;\n\n\t// Invalidate the column types as the new data needs to be revalidated\n\tfor ( var i=0, iLen=columns.length ; i iTarget )\n\t\t{\n\t\t\ta[i]--;\n\t\t}\n\t}\n\n\tif ( iTargetIndex != -1 && splice === undefined )\n\t{\n\t\ta.splice( iTargetIndex, 1 );\n\t}\n}\n\n\n/**\n * Mark cached data as invalid such that a re-read of the data will occur when\n * the cached data is next requested. Also update from the data source object.\n *\n * @param {object} settings DataTables settings object\n * @param {int} rowIdx Row index to invalidate\n * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'\n * or 'data'\n * @param {int} [colIdx] Column index to invalidate. If undefined the whole\n * row will be invalidated\n * @memberof DataTable#oApi\n *\n * @todo For the modularisation of v1.11 this will need to become a callback, so\n * the sort and filter methods can subscribe to it. That will required\n * initialisation options for sorting, which is why it is not already baked in\n */\nfunction _fnInvalidate( settings, rowIdx, src, colIdx )\n{\n\tvar row = settings.aoData[ rowIdx ];\n\tvar i, ien;\n\tvar cellWrite = function ( cell, col ) {\n\t\t// This is very frustrating, but in IE if you just write directly\n\t\t// to innerHTML, and elements that are overwritten are GC'ed,\n\t\t// even if there is a reference to them elsewhere\n\t\twhile ( cell.childNodes.length ) {\n\t\t\tcell.removeChild( cell.firstChild );\n\t\t}\n\n\t\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\n\t};\n\n\t// Are we reading last data from DOM or the data object?\n\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\n\t\t// Read the data from the DOM\n\t\trow._aData = _fnGetRowElements(\n\t\t\t\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\n\t\t\t)\n\t\t\t.data;\n\t}\n\telse {\n\t\t// Reading from data object, update the DOM\n\t\tvar cells = row.anCells;\n\n\t\tif ( cells ) {\n\t\t\tif ( colIdx !== undefined ) {\n\t\t\t\tcellWrite( cells[colIdx], colIdx );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfor ( i=0, ien=cells.length ; i').appendTo( thead );\n\t}\n\n\tfor ( i=0, ien=columns.length ; i=0 ; j-- )\n\t\t{\n\t\t\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\n\t\t\t{\n\t\t\t\taoLocal[i].splice( j, 1 );\n\t\t\t}\n\t\t}\n\n\t\t/* Prep the applied array - it needs an element for each row */\n\t\taApplied.push( [] );\n\t}\n\n\tfor ( i=0, iLen=aoLocal.length ; i', { 'class': iStripes ? asStripeClasses[0] : '' } )\n\t\t\t.append( $('
', {\n\t\t\t\t'valign': 'top',\n\t\t\t\t'colSpan': _fnVisbleColumns( oSettings ),\n\t\t\t\t'class': oSettings.oClasses.sRowEmpty\n\t\t\t} ).html( sZero ) )[0];\n\t}\n\n\t/* Header and footer callbacks */\n\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\n\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\n\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\n\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\n\tvar body = $(oSettings.nTBody);\n\n\tbody.children().detach();\n\tbody.append( $(anRows) );\n\n\t/* Call all required callback functions for the end of a draw */\n\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\n\n\t/* Draw is complete, sorting and filtering must be as well */\n\toSettings.bSorted = false;\n\toSettings.bFiltered = false;\n\toSettings.bDrawing = false;\n}\n\n\n/**\n * Redraw the table - taking account of the various features which are enabled\n * @param {object} oSettings dataTables settings object\n * @param {boolean} [holdPosition] Keep the current paging position. By default\n * the paging is reset to the first page\n * @memberof DataTable#oApi\n */\nfunction _fnReDraw( settings, holdPosition )\n{\n\tvar\n\t\tfeatures = settings.oFeatures,\n\t\tsort = features.bSort,\n\t\tfilter = features.bFilter;\n\n\tif ( sort ) {\n\t\t_fnSort( settings );\n\t}\n\n\tif ( filter ) {\n\t\t_fnFilterComplete( settings, settings.oPreviousSearch );\n\t}\n\telse {\n\t\t// No filtering, so we want to just use the display master\n\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t}\n\n\tif ( holdPosition !== true ) {\n\t\tsettings._iDisplayStart = 0;\n\t}\n\n\t// Let any modules know about the draw hold position state (used by\n\t// scrolling internally)\n\tsettings._drawHold = holdPosition;\n\n\t_fnDraw( settings );\n\n\tsettings._drawHold = false;\n}\n\n\n/**\n * Add the options to the page HTML for the table\n * @param {object} oSettings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnAddOptionsHtml ( oSettings )\n{\n\tvar classes = oSettings.oClasses;\n\tvar table = $(oSettings.nTable);\n\tvar holding = $('').insertBefore( table ); // Holding element for speed\n\tvar features = oSettings.oFeatures;\n\n\t// All DataTables are wrapped in a div\n\tvar insert = $('', {\n\t\tid: oSettings.sTableId+'_wrapper',\n\t\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\n\t} );\n\n\toSettings.nHolding = holding[0];\n\toSettings.nTableWrapper = insert[0];\n\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\n\n\t/* Loop over the user set positioning and place the elements as needed */\n\tvar aDom = oSettings.sDom.split('');\n\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\n\tfor ( var i=0 ; i')[0];\n\n\t\t\t/* Check to see if we should append an id and/or a class name to the container */\n\t\t\tcNext = aDom[i+1];\n\t\t\tif ( cNext == \"'\" || cNext == '\"' )\n\t\t\t{\n\t\t\t\tsAttr = \"\";\n\t\t\t\tj = 2;\n\t\t\t\twhile ( aDom[i+j] != cNext )\n\t\t\t\t{\n\t\t\t\t\tsAttr += aDom[i+j];\n\t\t\t\t\tj++;\n\t\t\t\t}\n\n\t\t\t\t/* Replace jQuery UI constants @todo depreciated */\n\t\t\t\tif ( sAttr == \"H\" )\n\t\t\t\t{\n\t\t\t\t\tsAttr = classes.sJUIHeader;\n\t\t\t\t}\n\t\t\t\telse if ( sAttr == \"F\" )\n\t\t\t\t{\n\t\t\t\t\tsAttr = classes.sJUIFooter;\n\t\t\t\t}\n\n\t\t\t\t/* The attribute can be in the format of \"#id.class\", \"#id\" or \"class\" This logic\n\t\t\t\t * breaks the string into parts and applies them as needed\n\t\t\t\t */\n\t\t\t\tif ( sAttr.indexOf('.') != -1 )\n\t\t\t\t{\n\t\t\t\t\tvar aSplit = sAttr.split('.');\n\t\t\t\t\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\n\t\t\t\t\tnNewNode.className = aSplit[1];\n\t\t\t\t}\n\t\t\t\telse if ( sAttr.charAt(0) == \"#\" )\n\t\t\t\t{\n\t\t\t\t\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnNewNode.className = sAttr;\n\t\t\t\t}\n\n\t\t\t\ti += j; /* Move along the position array */\n\t\t\t}\n\n\t\t\tinsert.append( nNewNode );\n\t\t\tinsert = $(nNewNode);\n\t\t}\n\t\telse if ( cOption == '>' )\n\t\t{\n\t\t\t/* End container div */\n\t\t\tinsert = insert.parent();\n\t\t}\n\t\t// @todo Move options into their own plugins?\n\t\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\n\t\t{\n\t\t\t/* Length */\n\t\t\tfeatureNode = _fnFeatureHtmlLength( oSettings );\n\t\t}\n\t\telse if ( cOption == 'f' && features.bFilter )\n\t\t{\n\t\t\t/* Filter */\n\t\t\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\n\t\t}\n\t\telse if ( cOption == 'r' && features.bProcessing )\n\t\t{\n\t\t\t/* pRocessing */\n\t\t\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\n\t\t}\n\t\telse if ( cOption == 't' )\n\t\t{\n\t\t\t/* Table */\n\t\t\tfeatureNode = _fnFeatureHtmlTable( oSettings );\n\t\t}\n\t\telse if ( cOption == 'i' && features.bInfo )\n\t\t{\n\t\t\t/* Info */\n\t\t\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\n\t\t}\n\t\telse if ( cOption == 'p' && features.bPaginate )\n\t\t{\n\t\t\t/* Pagination */\n\t\t\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\n\t\t}\n\t\telse if ( DataTable.ext.feature.length !== 0 )\n\t\t{\n\t\t\t/* Plug-in features */\n\t\t\tvar aoFeatures = DataTable.ext.feature;\n\t\t\tfor ( var k=0, kLen=aoFeatures.length ; k= oSettings.fnRecordsDisplay() ?\n\t\t\t\t0 :\n\t\t\t\tiInitDisplayStart;\n\n\t\toSettings.iInitDisplayStart = -1;\n\t}\n}\n\n/**\n * Create an Ajax call based on the table's settings, taking into account that\n * parameters can have multiple forms, and backwards compatibility.\n *\n * @param {object} oSettings dataTables settings object\n * @param {array} data Data to send to the server, required by\n * DataTables - may be augmented by developer callbacks\n * @param {function} fn Callback function to run when data is obtained\n */\nfunction _fnBuildAjax( oSettings, data, fn )\n{\n\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\n\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\n\n\t// Convert to object based for 1.10+ if using the old array scheme which can\n\t// come from server-side processing or serverParams\n\tif ( data && Array.isArray(data) ) {\n\t\tvar tmp = {};\n\t\tvar rbracket = /(.*?)\\[\\]$/;\n\n\t\t$.each( data, function (key, val) {\n\t\t\tvar match = val.name.match(rbracket);\n\n\t\t\tif ( match ) {\n\t\t\t\t// Support for arrays\n\t\t\t\tvar name = match[0];\n\n\t\t\t\tif ( ! tmp[ name ] ) {\n\t\t\t\t\ttmp[ name ] = [];\n\t\t\t\t}\n\t\t\t\ttmp[ name ].push( val.value );\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttmp[val.name] = val.value;\n\t\t\t}\n\t\t} );\n\t\tdata = tmp;\n\t}\n\n\tvar ajaxData;\n\tvar ajax = oSettings.ajax;\n\tvar instance = oSettings.oInstance;\n\tvar callback = function ( json ) {\n\t\tvar status = oSettings.jqXHR\n\t\t\t? oSettings.jqXHR.status\n\t\t\t: null;\n\n\t\tif ( json === null || (typeof status === 'number' && status == 204 ) ) {\n\t\t\tjson = {};\n\t\t\t_fnAjaxDataSrc( oSettings, json, [] );\n\t\t}\n\n\t\tvar error = json.error || json.sError;\n\t\tif ( error ) {\n\t\t\t_fnLog( oSettings, 0, error );\n\t\t}\n\n\t\toSettings.json = json;\n\n\t\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\n\t\tfn( json );\n\t};\n\n\tif ( $.isPlainObject( ajax ) && ajax.data )\n\t{\n\t\tajaxData = ajax.data;\n\n\t\tvar newData = typeof ajaxData === 'function' ?\n\t\t\tajaxData( data, oSettings ) : // fn can manipulate data or return\n\t\t\tajaxData; // an object object or array to merge\n\n\t\t// If the function returned something, use that alone\n\t\tdata = typeof ajaxData === 'function' && newData ?\n\t\t\tnewData :\n\t\t\t$.extend( true, data, newData );\n\n\t\t// Remove the data property as we've resolved it already and don't want\n\t\t// jQuery to do it again (it is restored at the end of the function)\n\t\tdelete ajax.data;\n\t}\n\n\tvar baseAjax = {\n\t\t\"data\": data,\n\t\t\"success\": callback,\n\t\t\"dataType\": \"json\",\n\t\t\"cache\": false,\n\t\t\"type\": oSettings.sServerMethod,\n\t\t\"error\": function (xhr, error, thrown) {\n\t\t\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\n\n\t\t\tif ( $.inArray( true, ret ) === -1 ) {\n\t\t\t\tif ( error == \"parsererror\" ) {\n\t\t\t\t\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\n\t\t\t\t}\n\t\t\t\telse if ( xhr.readyState === 4 ) {\n\t\t\t\t\t_fnLog( oSettings, 0, 'Ajax error', 7 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t}\n\t};\n\n\t// Store the data submitted for the API\n\toSettings.oAjaxData = data;\n\n\t// Allow plug-ins and external processes to modify the data\n\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\n\n\tif ( oSettings.fnServerData )\n\t{\n\t\t// DataTables 1.9- compatibility\n\t\toSettings.fnServerData.call( instance,\n\t\t\toSettings.sAjaxSource,\n\t\t\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\n\t\t\t\treturn { name: key, value: val };\n\t\t\t} ),\n\t\t\tcallback,\n\t\t\toSettings\n\t\t);\n\t}\n\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\n\t{\n\t\t// DataTables 1.9- compatibility\n\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\n\t\t\turl: ajax || oSettings.sAjaxSource\n\t\t} ) );\n\t}\n\telse if ( typeof ajax === 'function' )\n\t{\n\t\t// Is a function - let the caller define what needs to be done\n\t\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\n\t}\n\telse\n\t{\n\t\t// Object to extend the base settings\n\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\n\n\t\t// Restore for next time around\n\t\tajax.data = ajaxData;\n\t}\n}\n\n\n/**\n * Update the table using an Ajax call\n * @param {object} settings dataTables settings object\n * @returns {boolean} Block the table drawing or not\n * @memberof DataTable#oApi\n */\nfunction _fnAjaxUpdate( settings )\n{\n\tsettings.iDraw++;\n\t_fnProcessingDisplay( settings, true );\n\n\t// Keep track of drawHold state to handle scrolling after the Ajax call\n\tvar drawHold = settings._drawHold;\n\n\t_fnBuildAjax(\n\t\tsettings,\n\t\t_fnAjaxParameters( settings ),\n\t\tfunction(json) {\n\t\t\tsettings._drawHold = drawHold;\n\t\t\t_fnAjaxUpdateDraw( settings, json );\n\t\t\tsettings._drawHold = false;\n\t\t}\n\t);\n}\n\n\n/**\n * Build up the parameters in an object needed for a server-side processing\n * request. Note that this is basically done twice, is different ways - a modern\n * method which is used by default in DataTables 1.10 which uses objects and\n * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\n * the sAjaxSource option is used in the initialisation, or the legacyAjax\n * option is set.\n * @param {object} oSettings dataTables settings object\n * @returns {bool} block the table drawing or not\n * @memberof DataTable#oApi\n */\nfunction _fnAjaxParameters( settings )\n{\n\tvar\n\t\tcolumns = settings.aoColumns,\n\t\tcolumnCount = columns.length,\n\t\tfeatures = settings.oFeatures,\n\t\tpreSearch = settings.oPreviousSearch,\n\t\tpreColSearch = settings.aoPreSearchCols,\n\t\ti, data = [], dataProp, column, columnSearch,\n\t\tsort = _fnSortFlatten( settings ),\n\t\tdisplayStart = settings._iDisplayStart,\n\t\tdisplayLength = features.bPaginate !== false ?\n\t\t\tsettings._iDisplayLength :\n\t\t\t-1;\n\n\tvar param = function ( name, value ) {\n\t\tdata.push( { 'name': name, 'value': value } );\n\t};\n\n\t// DataTables 1.9- compatible method\n\tparam( 'sEcho', settings.iDraw );\n\tparam( 'iColumns', columnCount );\n\tparam( 'sColumns', _pluck( columns, 'sName' ).join(',') );\n\tparam( 'iDisplayStart', displayStart );\n\tparam( 'iDisplayLength', displayLength );\n\n\t// DataTables 1.10+ method\n\tvar d = {\n\t\tdraw: settings.iDraw,\n\t\tcolumns: [],\n\t\torder: [],\n\t\tstart: displayStart,\n\t\tlength: displayLength,\n\t\tsearch: {\n\t\t\tvalue: preSearch.sSearch,\n\t\t\tregex: preSearch.bRegex\n\t\t}\n\t};\n\n\tfor ( i=0 ; i';\n\n\tvar str = language.sSearch;\n\tstr = str.match(/_INPUT_/) ?\n\t\tstr.replace('_INPUT_', input) :\n\t\tstr+input;\n\n\tvar filter = $('', {\n\t\t\t'id': ! features.f ? tableId+'_filter' : null,\n\t\t\t'class': classes.sFilter\n\t\t} )\n\t\t.append( $('' ).append( str ) );\n\n\tvar searchFn = function(event) {\n\t\t/* Update all other filter input elements for the new display */\n\t\tvar n = features.f;\n\t\tvar val = !this.value ? \"\" : this.value; // mental IE8 fix :-(\n\t\tif(previousSearch['return'] && event.key !== \"Enter\") {\n\t\t\treturn;\n\t\t}\n\t\t/* Now do the filter */\n\t\tif ( val != previousSearch.sSearch ) {\n\t\t\t_fnFilterComplete( settings, {\n\t\t\t\t\"sSearch\": val,\n\t\t\t\t\"bRegex\": previousSearch.bRegex,\n\t\t\t\t\"bSmart\": previousSearch.bSmart ,\n\t\t\t\t\"bCaseInsensitive\": previousSearch.bCaseInsensitive,\n\t\t\t\t\"return\": previousSearch['return']\n\t\t\t} );\n\n\t\t\t// Need to redraw, without resorting\n\t\t\tsettings._iDisplayStart = 0;\n\t\t\t_fnDraw( settings );\n\t\t}\n\t};\n\n\tvar searchDelay = settings.searchDelay !== null ?\n\t\tsettings.searchDelay :\n\t\t_fnDataSource( settings ) === 'ssp' ?\n\t\t\t400 :\n\t\t\t0;\n\n\tvar jqFilter = $('input', filter)\n\t\t.val( previousSearch.sSearch )\n\t\t.attr( 'placeholder', language.sSearchPlaceholder )\n\t\t.on(\n\t\t\t'keyup.DT search.DT input.DT paste.DT cut.DT',\n\t\t\tsearchDelay ?\n\t\t\t\t_fnThrottle( searchFn, searchDelay ) :\n\t\t\t\tsearchFn\n\t\t)\n\t\t.on( 'mouseup.DT', function(e) {\n\t\t\t// Edge fix! Edge 17 does not trigger anything other than mouse events when clicking\n\t\t\t// on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`\n\t\t\t// checks the value to see if it has changed. In other browsers it won't have.\n\t\t\tsetTimeout( function () {\n\t\t\t\tsearchFn.call(jqFilter[0], e);\n\t\t\t}, 10);\n\t\t} )\n\t\t.on( 'keypress.DT', function(e) {\n\t\t\t/* Prevent form submission */\n\t\t\tif ( e.keyCode == 13 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} )\n\t\t.attr('aria-controls', tableId);\n\n\t// Update the input elements whenever the table is filtered\n\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\n\t\tif ( settings === s ) {\n\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t// inside an iframe or frame...\n\t\t\ttry {\n\t\t\t\tif ( jqFilter[0] !== document.activeElement ) {\n\t\t\t\t\tjqFilter.val( previousSearch.sSearch );\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch ( e ) {}\n\t\t}\n\t} );\n\n\treturn filter[0];\n}\n\n\n/**\n * Filter the table using both the global filter and column based filtering\n * @param {object} oSettings dataTables settings object\n * @param {object} oSearch search information\n * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\n * @memberof DataTable#oApi\n */\nfunction _fnFilterComplete ( oSettings, oInput, iForce )\n{\n\tvar oPrevSearch = oSettings.oPreviousSearch;\n\tvar aoPrevSearch = oSettings.aoPreSearchCols;\n\tvar fnSaveFilter = function ( oFilter ) {\n\t\t/* Save the filtering values */\n\t\toPrevSearch.sSearch = oFilter.sSearch;\n\t\toPrevSearch.bRegex = oFilter.bRegex;\n\t\toPrevSearch.bSmart = oFilter.bSmart;\n\t\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\n\t\toPrevSearch['return'] = oFilter['return'];\n\t};\n\tvar fnRegex = function ( o ) {\n\t\t// Backwards compatibility with the bEscapeRegex option\n\t\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\n\t};\n\n\t// Resolve any column types that are unknown due to addition or invalidation\n\t// @todo As per sort - can this be moved into an event handler?\n\t_fnColumnTypes( oSettings );\n\n\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\n\tif ( _fnDataSource( oSettings ) != 'ssp' )\n\t{\n\t\t/* Global filter */\n\t\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\n\t\tfnSaveFilter( oInput );\n\n\t\t/* Now do the individual column filter */\n\t\tfor ( var i=0 ; i input.length ||\n\t\t\t input.indexOf(prevSearch) !== 0 ||\n\t\t\t settings.bSorted // On resort, the display master needs to be\n\t\t\t // re-filtered since indexes will have changed\n\t\t) {\n\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t}\n\n\t\t// Search the display array\n\t\tdisplay = settings.aiDisplay;\n\n\t\tfor ( i=0 ; i')[0];\nvar __filter_div_textContent = __filter_div.textContent !== undefined;\n\n// Update the filtering data for each row if needed (by invalidation or first run)\nfunction _fnFilterData ( settings )\n{\n\tvar columns = settings.aoColumns;\n\tvar column;\n\tvar i, j, ien, jen, filterData, cellData, row;\n\tvar wasInvalidated = false;\n\n\tfor ( i=0, ien=settings.aoData.length ; i', {\n\t\t\t'class': settings.oClasses.sInfo,\n\t\t\t'id': ! nodes ? tid+'_info' : null\n\t\t} );\n\n\tif ( ! nodes ) {\n\t\t// Update display on each draw\n\t\tsettings.aoDrawCallback.push( {\n\t\t\t\"fn\": _fnUpdateInfo,\n\t\t\t\"sName\": \"information\"\n\t\t} );\n\n\t\tn\n\t\t\t.attr( 'role', 'status' )\n\t\t\t.attr( 'aria-live', 'polite' );\n\n\t\t// Table is described by our info div\n\t\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\n\t}\n\n\treturn n[0];\n}\n\n\n/**\n * Update the information elements in the display\n * @param {object} settings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnUpdateInfo ( settings )\n{\n\t/* Show information about the table */\n\tvar nodes = settings.aanFeatures.i;\n\tif ( nodes.length === 0 ) {\n\t\treturn;\n\t}\n\n\tvar\n\t\tlang = settings.oLanguage,\n\t\tstart = settings._iDisplayStart+1,\n\t\tend = settings.fnDisplayEnd(),\n\t\tmax = settings.fnRecordsTotal(),\n\t\ttotal = settings.fnRecordsDisplay(),\n\t\tout = total ?\n\t\t\tlang.sInfo :\n\t\t\tlang.sInfoEmpty;\n\n\tif ( total !== max ) {\n\t\t/* Record set after filtering */\n\t\tout += ' ' + lang.sInfoFiltered;\n\t}\n\n\t// Convert the macros\n\tout += lang.sInfoPostFix;\n\tout = _fnInfoMacros( settings, out );\n\n\tvar callback = lang.fnInfoCallback;\n\tif ( callback !== null ) {\n\t\tout = callback.call( settings.oInstance,\n\t\t\tsettings, start, end, max, total, out\n\t\t);\n\t}\n\n\t$(nodes).html( out );\n}\n\n\nfunction _fnInfoMacros ( settings, str )\n{\n\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\n\t// internally\n\tvar\n\t\tformatter = settings.fnFormatNumber,\n\t\tstart = settings._iDisplayStart+1,\n\t\tlen = settings._iDisplayLength,\n\t\tvis = settings.fnRecordsDisplay(),\n\t\tall = len === -1;\n\n\treturn str.\n\t\treplace(/_START_/g, formatter.call( settings, start ) ).\n\t\treplace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).\n\t\treplace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).\n\t\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\n\t\treplace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\n\t\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\n}\n\n\n\n/**\n * Draw the table for the first time, adding all required features\n * @param {object} settings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnInitialise ( settings )\n{\n\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\n\tvar columns = settings.aoColumns, column;\n\tvar features = settings.oFeatures;\n\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\n\n\t/* Ensure that the table data is fully initialised */\n\tif ( ! settings.bInitialised ) {\n\t\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\n\t\treturn;\n\t}\n\n\t/* Show the display HTML options */\n\t_fnAddOptionsHtml( settings );\n\n\t/* Build and draw the header / footer for the table */\n\t_fnBuildHead( settings );\n\t_fnDrawHead( settings, settings.aoHeader );\n\t_fnDrawHead( settings, settings.aoFooter );\n\n\t/* Okay to show that something is going on now */\n\t_fnProcessingDisplay( settings, true );\n\n\t/* Calculate sizes for columns */\n\tif ( features.bAutoWidth ) {\n\t\t_fnCalculateColumnWidths( settings );\n\t}\n\n\tfor ( i=0, iLen=columns.length ; i', {\n\t\t'name': tableId+'_length',\n\t\t'aria-controls': tableId,\n\t\t'class': classes.sLengthSelect\n\t} );\n\n\tfor ( var i=0, ien=lengths.length ; i').addClass( classes.sLength );\n\tif ( ! settings.aanFeatures.l ) {\n\t\tdiv[0].id = tableId+'_length';\n\t}\n\n\tdiv.children().append(\n\t\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\n\t);\n\n\t// Can't use `select` variable as user might provide their own and the\n\t// reference is broken by the use of outerHTML\n\t$('select', div)\n\t\t.val( settings._iDisplayLength )\n\t\t.on( 'change.DT', function(e) {\n\t\t\t_fnLengthChange( settings, $(this).val() );\n\t\t\t_fnDraw( settings );\n\t\t} );\n\n\t// Update node value whenever anything changes the table's length\n\t$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {\n\t\tif ( settings === s ) {\n\t\t\t$('select', div).val( len );\n\t\t}\n\t} );\n\n\treturn div[0];\n}\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Note that most of the paging logic is done in\n * DataTable.ext.pager\n */\n\n/**\n * Generate the node required for default pagination\n * @param {object} oSettings dataTables settings object\n * @returns {node} Pagination feature node\n * @memberof DataTable#oApi\n */\nfunction _fnFeatureHtmlPaginate ( settings )\n{\n\tvar\n\t\ttype = settings.sPaginationType,\n\t\tplugin = DataTable.ext.pager[ type ],\n\t\tmodern = typeof plugin === 'function',\n\t\tredraw = function( settings ) {\n\t\t\t_fnDraw( settings );\n\t\t},\n\t\tnode = $('').addClass( settings.oClasses.sPaging + type )[0],\n\t\tfeatures = settings.aanFeatures;\n\n\tif ( ! modern ) {\n\t\tplugin.fnInit( settings, node, redraw );\n\t}\n\n\t/* Add a draw callback for the pagination on first instance, to update the paging display */\n\tif ( ! features.p )\n\t{\n\t\tnode.id = settings.sTableId+'_paginate';\n\n\t\tsettings.aoDrawCallback.push( {\n\t\t\t\"fn\": function( settings ) {\n\t\t\t\tif ( modern ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tstart = settings._iDisplayStart,\n\t\t\t\t\t\tlen = settings._iDisplayLength,\n\t\t\t\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\t\t\t\tall = len === -1,\n\t\t\t\t\t\tpage = all ? 0 : Math.ceil( start / len ),\n\t\t\t\t\t\tpages = all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\t\t\tbuttons = plugin(page, pages),\n\t\t\t\t\t\ti, ien;\n\n\t\t\t\t\tfor ( i=0, ien=features.p.length ; i records )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t}\n\telse if ( action == \"first\" )\n\t{\n\t\tstart = 0;\n\t}\n\telse if ( action == \"previous\" )\n\t{\n\t\tstart = len >= 0 ?\n\t\t\tstart - len :\n\t\t\t0;\n\n\t\tif ( start < 0 )\n\t\t{\n\t\t start = 0;\n\t\t}\n\t}\n\telse if ( action == \"next\" )\n\t{\n\t\tif ( start + len < records )\n\t\t{\n\t\t\tstart += len;\n\t\t}\n\t}\n\telse if ( action == \"last\" )\n\t{\n\t\tstart = Math.floor( (records-1) / len) * len;\n\t}\n\telse\n\t{\n\t\t_fnLog( settings, 0, \"Unknown paging action: \"+action, 5 );\n\t}\n\n\tvar changed = settings._iDisplayStart !== start;\n\tsettings._iDisplayStart = start;\n\n\tif ( changed ) {\n\t\t_fnCallbackFire( settings, null, 'page', [settings] );\n\n\t\tif ( redraw ) {\n\t\t\t_fnDraw( settings );\n\t\t}\n\t}\n\telse {\n\t\t// No change event - paging was called, but no change\n\t\t_fnCallbackFire( settings, null, 'page-nc', [settings] );\n\t}\n\n\treturn changed;\n}\n\n\n\n/**\n * Generate the node required for the processing node\n * @param {object} settings dataTables settings object\n * @returns {node} Processing element\n * @memberof DataTable#oApi\n */\nfunction _fnFeatureHtmlProcessing ( settings )\n{\n\treturn $('', {\n\t\t\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\n\t\t\t'class': settings.oClasses.sProcessing,\n\t\t\t'role': 'status'\n\t\t} )\n\t\t.html( settings.oLanguage.sProcessing )\n\t\t.append('
')\n\t\t.insertBefore( settings.nTable )[0];\n}\n\n\n/**\n * Display or hide the processing indicator\n * @param {object} settings dataTables settings object\n * @param {bool} show Show the processing indicator (true) or not (false)\n * @memberof DataTable#oApi\n */\nfunction _fnProcessingDisplay ( settings, show )\n{\n\tif ( settings.oFeatures.bProcessing ) {\n\t\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\n\t}\n\n\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\n}\n\n/**\n * Add any control elements for the table - specifically scrolling\n * @param {object} settings dataTables settings object\n * @returns {node} Node to add to the DOM\n * @memberof DataTable#oApi\n */\nfunction _fnFeatureHtmlTable ( settings )\n{\n\tvar table = $(settings.nTable);\n\n\t// Scrolling from here on in\n\tvar scroll = settings.oScroll;\n\n\tif ( scroll.sX === '' && scroll.sY === '' ) {\n\t\treturn settings.nTable;\n\t}\n\n\tvar scrollX = scroll.sX;\n\tvar scrollY = scroll.sY;\n\tvar classes = settings.oClasses;\n\tvar caption = table.children('caption');\n\tvar captionSide = caption.length ? caption[0]._captionSide : null;\n\tvar headerClone = $( table[0].cloneNode(false) );\n\tvar footerClone = $( table[0].cloneNode(false) );\n\tvar footer = table.children('tfoot');\n\tvar _div = '';\n\tvar size = function ( s ) {\n\t\treturn !s ? null : _fnStringToCss( s );\n\t};\n\n\tif ( ! footer.length ) {\n\t\tfooter = null;\n\t}\n\n\t/*\n\t * The HTML structure that we want to generate in this function is:\n\t * div - scroller\n\t * div - scroll head\n\t * div - scroll head inner\n\t * table - scroll head table\n\t * thead - thead\n\t * div - scroll body\n\t * table - table (master table)\n\t * thead - thead clone for sizing\n\t * tbody - tbody\n\t * div - scroll foot\n\t * div - scroll foot inner\n\t * table - scroll foot table\n\t * tfoot - tfoot\n\t */\n\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\n\t\t.append(\n\t\t\t$(_div, { 'class': classes.sScrollHead } )\n\t\t\t\t.css( {\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\tposition: 'relative',\n\t\t\t\t\tborder: 0,\n\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t} )\n\t\t\t\t.append(\n\t\t\t\t\t$(_div, { 'class': classes.sScrollHeadInner } )\n\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t'box-sizing': 'content-box',\n\t\t\t\t\t\t\twidth: scroll.sXInner || '100%'\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\theaderClone\n\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t.append( captionSide === 'top' ? caption : null )\n\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\ttable.children('thead')\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t)\n\t\t.append(\n\t\t\t$(_div, { 'class': classes.sScrollBody } )\n\t\t\t\t.css( {\n\t\t\t\t\tposition: 'relative',\n\t\t\t\t\toverflow: 'auto',\n\t\t\t\t\twidth: size( scrollX )\n\t\t\t\t} )\n\t\t\t\t.append( table )\n\t\t);\n\n\tif ( footer ) {\n\t\tscroller.append(\n\t\t\t$(_div, { 'class': classes.sScrollFoot } )\n\t\t\t\t.css( {\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\tborder: 0,\n\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t} )\n\t\t\t\t.append(\n\t\t\t\t\t$(_div, { 'class': classes.sScrollFootInner } )\n\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\tfooterClone\n\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t.append( captionSide === 'bottom' ? caption : null )\n\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\ttable.children('tfoot')\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t);\n\t}\n\n\tvar children = scroller.children();\n\tvar scrollHead = children[0];\n\tvar scrollBody = children[1];\n\tvar scrollFoot = footer ? children[2] : null;\n\n\t// When the body is scrolled, then we also want to scroll the headers\n\tif ( scrollX ) {\n\t\t$(scrollBody).on( 'scroll.DT', function (e) {\n\t\t\tvar scrollLeft = this.scrollLeft;\n\n\t\t\tscrollHead.scrollLeft = scrollLeft;\n\n\t\t\tif ( footer ) {\n\t\t\t\tscrollFoot.scrollLeft = scrollLeft;\n\t\t\t}\n\t\t} );\n\t}\n\n\t$(scrollBody).css('max-height', scrollY);\n\tif (! scroll.bCollapse) {\n\t\t$(scrollBody).css('height', scrollY);\n\t}\n\n\tsettings.nScrollHead = scrollHead;\n\tsettings.nScrollBody = scrollBody;\n\tsettings.nScrollFoot = scrollFoot;\n\n\t// On redraw - align columns\n\tsettings.aoDrawCallback.push( {\n\t\t\"fn\": _fnScrollDraw,\n\t\t\"sName\": \"scrolling\"\n\t} );\n\n\treturn scroller[0];\n}\n\n\n\n/**\n * Update the header, footer and body tables for resizing - i.e. column\n * alignment.\n *\n * Welcome to the most horrible function DataTables. The process that this\n * function follows is basically:\n * 1. Re-create the table inside the scrolling div\n * 2. Take live measurements from the DOM\n * 3. Apply the measurements to align the columns\n * 4. Clean up\n *\n * @param {object} settings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnScrollDraw ( settings )\n{\n\t// Given that this is such a monster function, a lot of variables are use\n\t// to try and keep the minimised size as small as possible\n\tvar\n\t\tscroll = settings.oScroll,\n\t\tscrollX = scroll.sX,\n\t\tscrollXInner = scroll.sXInner,\n\t\tscrollY = scroll.sY,\n\t\tbarWidth = scroll.iBarWidth,\n\t\tdivHeader = $(settings.nScrollHead),\n\t\tdivHeaderStyle = divHeader[0].style,\n\t\tdivHeaderInner = divHeader.children('div'),\n\t\tdivHeaderInnerStyle = divHeaderInner[0].style,\n\t\tdivHeaderTable = divHeaderInner.children('table'),\n\t\tdivBodyEl = settings.nScrollBody,\n\t\tdivBody = $(divBodyEl),\n\t\tdivBodyStyle = divBodyEl.style,\n\t\tdivFooter = $(settings.nScrollFoot),\n\t\tdivFooterInner = divFooter.children('div'),\n\t\tdivFooterTable = divFooterInner.children('table'),\n\t\theader = $(settings.nTHead),\n\t\ttable = $(settings.nTable),\n\t\ttableEl = table[0],\n\t\ttableStyle = tableEl.style,\n\t\tfooter = settings.nTFoot ? $(settings.nTFoot) : null,\n\t\tbrowser = settings.oBrowser,\n\t\tie67 = browser.bScrollOversize,\n\t\tdtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),\n\t\theaderTrgEls, footerTrgEls,\n\t\theaderSrcEls, footerSrcEls,\n\t\theaderCopy, footerCopy,\n\t\theaderWidths=[], footerWidths=[],\n\t\theaderContent=[], footerContent=[],\n\t\tidx, correction, sanityWidth,\n\t\tzeroOut = function(nSizer) {\n\t\t\tvar style = nSizer.style;\n\t\t\tstyle.paddingTop = \"0\";\n\t\t\tstyle.paddingBottom = \"0\";\n\t\t\tstyle.borderTopWidth = \"0\";\n\t\t\tstyle.borderBottomWidth = \"0\";\n\t\t\tstyle.height = 0;\n\t\t};\n\n\t// If the scrollbar visibility has changed from the last draw, we need to\n\t// adjust the column sizes as the table width will have changed to account\n\t// for the scrollbar\n\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\n\t\n\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\n\t\tsettings.scrollBarVis = scrollBarVis;\n\t\t_fnAdjustColumnSizing( settings );\n\t\treturn; // adjust column sizing will call this function again\n\t}\n\telse {\n\t\tsettings.scrollBarVis = scrollBarVis;\n\t}\n\n\t/*\n\t * 1. Re-create the table inside the scrolling div\n\t */\n\n\t// Remove the old minimised thead and tfoot elements in the inner table\n\ttable.children('thead, tfoot').remove();\n\n\tif ( footer ) {\n\t\tfooterCopy = footer.clone().prependTo( table );\n\t\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\n\t\tfooterSrcEls = footerCopy.find('tr');\n\t\tfooterCopy.find('[id]').removeAttr('id');\n\t}\n\n\t// Clone the current header and footer elements and then place it into the inner table\n\theaderCopy = header.clone().prependTo( table );\n\theaderTrgEls = header.find('tr'); // original header is in its own table\n\theaderSrcEls = headerCopy.find('tr');\n\theaderCopy.find('th, td').removeAttr('tabindex');\n\theaderCopy.find('[id]').removeAttr('id');\n\n\n\t/*\n\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\n\t */\n\n\t// Remove old sizing and apply the calculated column widths\n\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\n\t// calculated sizes to this header\n\tif ( ! scrollX )\n\t{\n\t\tdivBodyStyle.width = '100%';\n\t\tdivHeader[0].style.width = '100%';\n\t}\n\n\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\n\t\tidx = _fnVisibleToColumnIndex( settings, i );\n\t\tel.style.width = settings.aoColumns[idx].sWidth;\n\t} );\n\n\tif ( footer ) {\n\t\t_fnApplyToChildren( function(n) {\n\t\t\tn.style.width = \"\";\n\t\t}, footerSrcEls );\n\t}\n\n\t// Size the table as a whole\n\tsanityWidth = table.outerWidth();\n\tif ( scrollX === \"\" ) {\n\t\t// No x scrolling\n\t\ttableStyle.width = \"100%\";\n\n\t\t// IE7 will make the width of the table when 100% include the scrollbar\n\t\t// - which is shouldn't. When there is a scrollbar we need to take this\n\t\t// into account.\n\t\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\n\t\t\tdivBody.css('overflow-y') == \"scroll\")\n\t\t) {\n\t\t\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\n\t\t}\n\n\t\t// Recalculate the sanity width\n\t\tsanityWidth = table.outerWidth();\n\t}\n\telse if ( scrollXInner !== \"\" ) {\n\t\t// legacy x scroll inner has been given - use it\n\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n\n\t\t// Recalculate the sanity width\n\t\tsanityWidth = table.outerWidth();\n\t}\n\n\t// Hidden header should have zero height, so remove padding and borders. Then\n\t// set the width based on the real headers\n\n\t// Apply all styles in one pass\n\t_fnApplyToChildren( zeroOut, headerSrcEls );\n\n\t// Read all widths in next pass\n\t_fnApplyToChildren( function(nSizer) {\n\t\tvar style = window.getComputedStyle ?\n\t\t\twindow.getComputedStyle(nSizer).width :\n\t\t\t_fnStringToCss( $(nSizer).width() );\n\n\t\theaderContent.push( nSizer.innerHTML );\n\t\theaderWidths.push( style );\n\t}, headerSrcEls );\n\n\t// Apply all widths in final pass\n\t_fnApplyToChildren( function(nToSize, i) {\n\t\tnToSize.style.width = headerWidths[i];\n\t}, headerTrgEls );\n\n\t$(headerSrcEls).css('height', 0);\n\n\t/* Same again with the footer if we have one */\n\tif ( footer )\n\t{\n\t\t_fnApplyToChildren( zeroOut, footerSrcEls );\n\n\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\tfooterContent.push( nSizer.innerHTML );\n\t\t\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t}, footerSrcEls );\n\n\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\tnToSize.style.width = footerWidths[i];\n\t\t}, footerTrgEls );\n\n\t\t$(footerSrcEls).height(0);\n\t}\n\n\n\t/*\n\t * 3. Apply the measurements\n\t */\n\n\t// \"Hide\" the header and footer that we used for the sizing. We need to keep\n\t// the content of the cell so that the width applied to the header and body\n\t// both match, but we want to hide it completely. We want to also fix their\n\t// width to what they currently are\n\t_fnApplyToChildren( function(nSizer, i) {\n\t\tnSizer.innerHTML = '
';\n\t\t\tnSizer.childNodes[0].style.height = \"0\";\n\t\t\tnSizer.childNodes[0].style.overflow = \"hidden\";\n\t\t\tnSizer.style.width = footerWidths[i];\n\t\t}, footerSrcEls );\n\t}\n\n\t// Sanity check that the table is of a sensible width. If not then we are going to get\n\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\n\tif ( Math.round(table.outerWidth()) < Math.round(sanityWidth) )\n\t{\n\t\t// The min width depends upon if we have a vertical scrollbar visible or not */\n\t\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\n\t\t\tdivBody.css('overflow-y') == \"scroll\")) ?\n\t\t\t\tsanityWidth+barWidth :\n\t\t\t\tsanityWidth;\n\n\t\t// IE6/7 are a law unto themselves...\n\t\tif ( ie67 && (divBodyEl.scrollHeight >\n\t\t\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \"scroll\")\n\t\t) {\n\t\t\ttableStyle.width = _fnStringToCss( correction-barWidth );\n\t\t}\n\n\t\t// And give the user a warning that we've stopped the table getting too small\n\t\tif ( scrollX === \"\" || scrollXInner !== \"\" ) {\n\t\t\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\n\t\t}\n\t}\n\telse\n\t{\n\t\tcorrection = '100%';\n\t}\n\n\t// Apply to the container elements\n\tdivBodyStyle.width = _fnStringToCss( correction );\n\tdivHeaderStyle.width = _fnStringToCss( correction );\n\n\tif ( footer ) {\n\t\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\n\t}\n\n\n\t/*\n\t * 4. Clean up\n\t */\n\tif ( ! scrollY ) {\n\t\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\n\t\t * the scrollbar height from the visible display, rather than adding it on. We need to\n\t\t * set the height in order to sort this. Don't want to do it in any other browsers.\n\t\t */\n\t\tif ( ie67 ) {\n\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\n\t\t}\n\t}\n\n\t/* Finally set the width's of the header and footer tables */\n\tvar iOuterWidth = table.outerWidth();\n\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\n\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\n\n\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\n\t// provide a bit more space to allow \"overflow\" scrolling (i.e. past the scrollbar)\n\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \"scroll\";\n\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\n\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\"px\" : \"0px\";\n\n\tif ( footer ) {\n\t\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\n\t\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t}\n\n\t// Correct DOM ordering for colgroup - comes before the thead\n\ttable.children('colgroup').insertBefore( table.children('thead') );\n\n\t/* Adjust the position of the header in case we loose the y-scrollbar */\n\tdivBody.trigger('scroll');\n\n\t// If sorting or filtering has occurred, jump the scrolling back to the top\n\t// only if we aren't holding the position\n\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\n\t\tdivBodyEl.scrollTop = 0;\n\t}\n}\n\n\n\n/**\n * Apply a given function to the display child nodes of an element array (typically\n * TD children of TR rows\n * @param {function} fn Method to apply to the objects\n * @param array {nodes} an1 List of elements to look through for display children\n * @param array {nodes} an2 Another list (identical structure to the first) - optional\n * @memberof DataTable#oApi\n */\nfunction _fnApplyToChildren( fn, an1, an2 )\n{\n\tvar index=0, i=0, iLen=an1.length;\n\tvar nNode1, nNode2;\n\n\twhile ( i < iLen ) {\n\t\tnNode1 = an1[i].firstChild;\n\t\tnNode2 = an2 ? an2[i].firstChild : null;\n\n\t\twhile ( nNode1 ) {\n\t\t\tif ( nNode1.nodeType === 1 ) {\n\t\t\t\tif ( an2 ) {\n\t\t\t\t\tfn( nNode1, nNode2, index );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfn( nNode1, index );\n\t\t\t\t}\n\n\t\t\t\tindex++;\n\t\t\t}\n\n\t\t\tnNode1 = nNode1.nextSibling;\n\t\t\tnNode2 = an2 ? nNode2.nextSibling : null;\n\t\t}\n\n\t\ti++;\n\t}\n}\n\n\n\nvar __re_html_remove = /<.*?>/g;\n\n\n/**\n * Calculate the width of columns for the table\n * @param {object} oSettings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnCalculateColumnWidths ( oSettings )\n{\n\tvar\n\t\ttable = oSettings.nTable,\n\t\tcolumns = oSettings.aoColumns,\n\t\tscroll = oSettings.oScroll,\n\t\tscrollY = scroll.sY,\n\t\tscrollX = scroll.sX,\n\t\tscrollXInner = scroll.sXInner,\n\t\tcolumnCount = columns.length,\n\t\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\n\t\theaderCells = $('th', oSettings.nTHead),\n\t\ttableWidthAttr = table.getAttribute('width'), // from DOM element\n\t\ttableContainer = table.parentNode,\n\t\tuserInputs = false,\n\t\ti, column, columnIdx, width, outerWidth,\n\t\tbrowser = oSettings.oBrowser,\n\t\tie67 = browser.bScrollOversize;\n\n\tvar styleWidth = table.style.width;\n\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\n\t\ttableWidthAttr = styleWidth;\n\t}\n\n\t/* Convert any user input sizes into pixel sizes */\n\tvar sizes = _fnConvertToWidth(_pluck(columns, 'sWidthOrig'), tableContainer);\n\n\tfor ( i=0 ; i').appendTo( tmpTable.find('tbody') );\n\n\t\t// Clone the table header and footer - we can't use the header / footer\n\t\t// from the cloned table, since if scrolling is active, the table's\n\t\t// real header and footer are contained in different table tags\n\t\ttmpTable.find('thead, tfoot').remove();\n\t\ttmpTable\n\t\t\t.append( $(oSettings.nTHead).clone() )\n\t\t\t.append( $(oSettings.nTFoot).clone() );\n\n\t\t// Remove any assigned widths from the footer (from scrolling)\n\t\ttmpTable.find('tfoot th, tfoot td').css('width', '');\n\n\t\t// Apply custom sizing to the cloned header\n\t\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\n\n\t\tfor ( i=0 ; i').css( {\n\t\t\t\t\twidth: column.sWidthOrig,\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\tborder: 0,\n\t\t\t\t\theight: 1\n\t\t\t\t} ) );\n\t\t\t}\n\t\t}\n\n\t\t// Find the widest cell for each column and put it into the table\n\t\tif ( oSettings.aoData.length ) {\n\t\t\tfor ( i=0 ; i').css( scrollX || scrollY ?\n\t\t\t\t{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\theight: 1,\n\t\t\t\t\tright: 0,\n\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t} :\n\t\t\t\t{}\n\t\t\t)\n\t\t\t.append( tmpTable )\n\t\t\t.appendTo( tableContainer );\n\n\t\t// When scrolling (X or Y) we want to set the width of the table as \n\t\t// appropriate. However, when not scrolling leave the table width as it\n\t\t// is. This results in slightly different, but I think correct behaviour\n\t\tif ( scrollX && scrollXInner ) {\n\t\t\ttmpTable.width( scrollXInner );\n\t\t}\n\t\telse if ( scrollX ) {\n\t\t\ttmpTable.css( 'width', 'auto' );\n\t\t\ttmpTable.removeAttr('width');\n\n\t\t\t// If there is no width attribute or style, then allow the table to\n\t\t\t// collapse\n\t\t\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\n\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t\t}\n\t\t}\n\t\telse if ( scrollY ) {\n\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t}\n\t\telse if ( tableWidthAttr ) {\n\t\t\ttmpTable.width( tableWidthAttr );\n\t\t}\n\n\t\t// Get the width of each column in the constructed table - we need to\n\t\t// know the inner width (so it can be assigned to the other table's\n\t\t// cells) and the outer width so we can calculate the full width of the\n\t\t// table. This is safe since DataTables requires a unique cell for each\n\t\t// column, but if ever a header can span multiple columns, this will\n\t\t// need to be modified.\n\t\tvar total = 0;\n\t\tfor ( i=0 ; i')\n\t\t\t\t\t.css( 'width', _fnStringToCss( widths[i] ) )\n\t\t\t\t\t.appendTo( parent || document.body )\n\t\t\t)\n\t\t}\n\t\telse {\n\t\t\tels.push(null);\n\t\t}\n\t}\n\n\t// Get the sizes (will reflow once)\n\tfor (var i=0 ; i').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\n\t\tdata.anCells[ colIdx ];\n}\n\n\n/**\n * Get the maximum strlen for each data column\n * @param {object} settings dataTables settings object\n * @param {int} colIdx column of interest\n * @returns {string} max string length for each column\n * @memberof DataTable#oApi\n */\nfunction _fnGetMaxLenString( settings, colIdx )\n{\n\tvar s, max=-1, maxIdx = -1;\n\n\tfor ( var i=0, ien=settings.aoData.length ; i max ) {\n\t\t\tmax = s.length;\n\t\t\tmaxIdx = i;\n\t\t}\n\t}\n\n\treturn maxIdx;\n}\n\n\n/**\n * Append a CSS unit (only if required) to a string\n * @param {string} value to css-ify\n * @returns {string} value with css unit\n * @memberof DataTable#oApi\n */\nfunction _fnStringToCss( s )\n{\n\tif ( s === null ) {\n\t\treturn '0px';\n\t}\n\n\tif ( typeof s == 'number' ) {\n\t\treturn s < 0 ?\n\t\t\t'0px' :\n\t\t\ts+'px';\n\t}\n\n\t// Check it has a unit character already\n\treturn s.match(/\\d$/) ?\n\t\ts+'px' :\n\t\ts;\n}\n\n\n\nfunction _fnSortFlatten ( settings )\n{\n\tvar\n\t\ti, iLen, k, kLen,\n\t\taSort = [],\n\t\taiOrig = [],\n\t\taoColumns = settings.aoColumns,\n\t\taDataSort, iCol, sType, srcCol,\n\t\tfixed = settings.aaSortingFixed,\n\t\tfixedObj = $.isPlainObject( fixed ),\n\t\tnestedSort = [],\n\t\tadd = function ( a ) {\n\t\t\tif ( a.length && ! Array.isArray( a[0] ) ) {\n\t\t\t\t// 1D array\n\t\t\t\tnestedSort.push( a );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// 2D array\n\t\t\t\t$.merge( nestedSort, a );\n\t\t\t}\n\t\t};\n\n\t// Build the sort array, with pre-fix and post-fix options if they have been\n\t// specified\n\tif ( Array.isArray( fixed ) ) {\n\t\tadd( fixed );\n\t}\n\n\tif ( fixedObj && fixed.pre ) {\n\t\tadd( fixed.pre );\n\t}\n\n\tadd( settings.aaSorting );\n\n\tif (fixedObj && fixed.post ) {\n\t\tadd( fixed.post );\n\t}\n\n\tfor ( i=0 ; iy ? 1 : 0;\n\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\treturn sort.dir === 'asc' ? test : -test;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tx = aiOrig[a];\n\t\t\t\ty = aiOrig[b];\n\t\t\t\treturn xy ? 1 : 0;\n\t\t\t} );\n\t\t}\n\t\telse {\n\t\t\t// Depreciated - remove in 1.11 (providing a plug-in option)\n\t\t\t// Not all sort types have formatting methods, so we have to call their sorting\n\t\t\t// methods.\n\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\tvar\n\t\t\t\t\tx, y, k, l, test, sort, fn,\n\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\tdataB = aoData[b]._aSortData;\n\n\t\t\t\tfor ( k=0 ; ky ? 1 : 0;\n\t\t\t} );\n\t\t}\n\t}\n\n\t/* Tell the draw function that we have sorted the data */\n\toSettings.bSorted = true;\n}\n\n\nfunction _fnSortAria ( settings )\n{\n\tvar label;\n\tvar nextSort;\n\tvar columns = settings.aoColumns;\n\tvar aSort = _fnSortFlatten( settings );\n\tvar oAria = settings.oLanguage.oAria;\n\n\t// ARIA attributes - need to loop all columns, to update all (removing old\n\t// attributes as needed)\n\tfor ( var i=0, iLen=columns.length ; i/g, \"\" );\n\t\tvar th = col.nTh;\n\n\t\t// IE7 is throwing an error when setting these properties with jQuery's\n\t\t// attr() and removeAttr() methods...\n\t\tth.removeAttribute('aria-sort');\n\n\t\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\n\t\tif ( col.bSortable ) {\n\t\t\tif ( aSort.length > 0 && aSort[0].col == i ) {\n\t\t\t\tth.setAttribute('aria-sort', aSort[0].dir==\"asc\" ? \"ascending\" : \"descending\" );\n\t\t\t\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnextSort = asSorting[0];\n\t\t\t}\n\n\t\t\tlabel = sTitle + ( nextSort === \"asc\" ?\n\t\t\t\toAria.sSortAscending :\n\t\t\t\toAria.sSortDescending\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tlabel = sTitle;\n\t\t}\n\n\t\tth.setAttribute('aria-label', label);\n\t}\n}\n\n\n/**\n * Function to run on user sort request\n * @param {object} settings dataTables settings object\n * @param {node} attachTo node to attach the handler to\n * @param {int} colIdx column sorting index\n * @param {boolean} [append=false] Append the requested sort to the existing\n * sort if true (i.e. multi-column sort)\n * @param {function} [callback] callback function\n * @memberof DataTable#oApi\n */\nfunction _fnSortListener ( settings, colIdx, append, callback )\n{\n\tvar col = settings.aoColumns[ colIdx ];\n\tvar sorting = settings.aaSorting;\n\tvar asSorting = col.asSorting;\n\tvar nextSortIdx;\n\tvar next = function ( a, overflow ) {\n\t\tvar idx = a._idx;\n\t\tif ( idx === undefined ) {\n\t\t\tidx = $.inArray( a[1], asSorting );\n\t\t}\n\n\t\treturn idx+1 < asSorting.length ?\n\t\t\tidx+1 :\n\t\t\toverflow ?\n\t\t\t\tnull :\n\t\t\t\t0;\n\t};\n\n\t// Convert to 2D array if needed\n\tif ( typeof sorting[0] === 'number' ) {\n\t\tsorting = settings.aaSorting = [ sorting ];\n\t}\n\n\t// If appending the sort then we are multi-column sorting\n\tif ( append && settings.oFeatures.bSortMulti ) {\n\t\t// Are we already doing some kind of sort on this column?\n\t\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\n\n\t\tif ( sortIdx !== -1 ) {\n\t\t\t// Yes, modify the sort\n\t\t\tnextSortIdx = next( sorting[sortIdx], true );\n\n\t\t\tif ( nextSortIdx === null && sorting.length === 1 ) {\n\t\t\t\tnextSortIdx = 0; // can't remove sorting completely\n\t\t\t}\n\n\t\t\tif ( nextSortIdx === null ) {\n\t\t\t\tsorting.splice( sortIdx, 1 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\n\t\t\t\tsorting[sortIdx]._idx = nextSortIdx;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// No sort on this column yet\n\t\t\tsorting.push( [ colIdx, asSorting[0], 0 ] );\n\t\t\tsorting[sorting.length-1]._idx = 0;\n\t\t}\n\t}\n\telse if ( sorting.length && sorting[0][0] == colIdx ) {\n\t\t// Single column - already sorting on this column, modify the sort\n\t\tnextSortIdx = next( sorting[0] );\n\n\t\tsorting.length = 1;\n\t\tsorting[0][1] = asSorting[ nextSortIdx ];\n\t\tsorting[0]._idx = nextSortIdx;\n\t}\n\telse {\n\t\t// Single column - sort only on this column\n\t\tsorting.length = 0;\n\t\tsorting.push( [ colIdx, asSorting[0] ] );\n\t\tsorting[0]._idx = 0;\n\t}\n\n\t// Run the sort by calling a full redraw\n\t_fnReDraw( settings );\n\n\t// callback used for async user interaction\n\tif ( typeof callback == 'function' ) {\n\t\tcallback( settings );\n\t}\n}\n\n\n/**\n * Attach a sort handler (click) to a node\n * @param {object} settings dataTables settings object\n * @param {node} attachTo node to attach the handler to\n * @param {int} colIdx column sorting index\n * @param {function} [callback] callback function\n * @memberof DataTable#oApi\n */\nfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\n{\n\tvar col = settings.aoColumns[ colIdx ];\n\n\t_fnBindAction( attachTo, {}, function (e) {\n\t\t/* If the column is not sortable - don't to anything */\n\t\tif ( col.bSortable === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If processing is enabled use a timeout to allow the processing\n\t\t// display to be shown - otherwise to it synchronously\n\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t_fnProcessingDisplay( settings, true );\n\n\t\t\tsetTimeout( function() {\n\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\n\t\t\t\t// In server-side processing, the draw callback will remove the\n\t\t\t\t// processing display\n\t\t\t\tif ( _fnDataSource( settings ) !== 'ssp' ) {\n\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t}\n\t\t\t}, 0 );\n\t\t}\n\t\telse {\n\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\t}\n\t} );\n}\n\n\n/**\n * Set the sorting classes on table's body, Note: it is safe to call this function\n * when bSort and bSortClasses are false\n * @param {object} oSettings dataTables settings object\n * @memberof DataTable#oApi\n */\nfunction _fnSortingClasses( settings )\n{\n\tvar oldSort = settings.aLastSort;\n\tvar sortClass = settings.oClasses.sSortColumn;\n\tvar sort = _fnSortFlatten( settings );\n\tvar features = settings.oFeatures;\n\tvar i, ien, colIdx;\n\n\tif ( features.bSort && features.bSortClasses ) {\n\t\t// Remove old sorting classes\n\t\tfor ( i=0, ien=oldSort.length ; i 0 && s.time < +new Date() - (duration*1000) ) {\n\t\tsettings._bLoadingState = false;\n\t\tcallback();\n\t\treturn;\n\t}\n\n\t// Number of columns have changed - all bets are off, no restore of settings\n\tif ( s.columns && columns.length !== s.columns.length ) {\n\t\tsettings._bLoadingState = false;\n\t\tcallback();\n\t\treturn;\n\t}\n\n\t// Store the saved state so it might be accessed at any time\n\tsettings.oLoadedState = $.extend( true, {}, s );\n\n\t// Page Length\n\tif ( s.length !== undefined ) {\n\t\t// If already initialised just set the value directly so that the select element is also updated\n\t\tif (api) {\n\t\t\tapi.page.len(s.length)\n\t\t}\n\t\telse {\n\t\t\tsettings._iDisplayLength = s.length;\n\t\t}\n\t}\n\n\t// Restore key features - todo - for 1.11 this needs to be done by\n\t// subscribed events\n\tif ( s.start !== undefined ) {\n\t\tif(api === null) {\n\t\t\tsettings._iDisplayStart = s.start;\n\t\t\tsettings.iInitDisplayStart = s.start;\n\t\t}\n\t\telse {\n\t\t\t_fnPageChange(settings, s.start/settings._iDisplayLength);\n\t\t}\n\t}\n\n\t// Order\n\tif ( s.order !== undefined ) {\n\t\tsettings.aaSorting = [];\n\t\t$.each( s.order, function ( i, col ) {\n\t\t\tsettings.aaSorting.push( col[0] >= columns.length ?\n\t\t\t\t[ 0, col[1] ] :\n\t\t\t\tcol\n\t\t\t);\n\t\t} );\n\t}\n\n\t// Search\n\tif ( s.search !== undefined ) {\n\t\t$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );\n\t}\n\n\t// Columns\n\tif ( s.columns ) {\n\t\tfor ( i=0, ien=s.columns.length ; i= end )\n\t{\n\t\tstart = end - len;\n\t}\n\n\t// Keep the start record on the current page\n\tstart -= (start % len);\n\n\tif ( len === -1 || start < 0 )\n\t{\n\t\tstart = 0;\n\t}\n\n\tsettings._iDisplayStart = start;\n}\n\n\nfunction _fnRenderer( settings, type )\n{\n\tvar renderer = settings.renderer;\n\tvar host = DataTable.ext.renderer[type];\n\n\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\n\t\t// Specific renderer for this type. If available use it, otherwise use\n\t\t// the default.\n\t\treturn host[renderer[type]] || host._;\n\t}\n\telse if ( typeof renderer === 'string' ) {\n\t\t// Common renderer - if there is one available for this type use it,\n\t\t// otherwise use the default\n\t\treturn host[renderer] || host._;\n\t}\n\n\t// Use the default\n\treturn host._;\n}\n\n\n/**\n * Detect the data source being used for the table. Used to simplify the code\n * a little (ajax) and to make it compress a little smaller.\n *\n * @param {object} settings dataTables settings object\n * @returns {string} Data source\n * @memberof DataTable#oApi\n */\nfunction _fnDataSource ( settings )\n{\n\tif ( settings.oFeatures.bServerSide ) {\n\t\treturn 'ssp';\n\t}\n\telse if ( settings.ajax || settings.sAjaxSource ) {\n\t\treturn 'ajax';\n\t}\n\treturn 'dom';\n}\n\n\n\n\n/**\n * Computed structure of the DataTables API, defined by the options passed to\n * `DataTable.Api.register()` when building the API.\n *\n * The structure is built in order to speed creation and extension of the Api\n * objects since the extensions are effectively pre-parsed.\n *\n * The array is an array of objects with the following structure, where this\n * base array represents the Api prototype base:\n *\n * [\n * {\n * name: 'data' -- string - Property name\n * val: function () {}, -- function - Api method (or undefined if just an object\n * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\n * propExt: [ ... ] -- array - Array of Api object definitions to extend the property\n * },\n * {\n * name: 'row'\n * val: {},\n * methodExt: [ ... ],\n * propExt: [\n * {\n * name: 'data'\n * val: function () {},\n * methodExt: [ ... ],\n * propExt: [ ... ]\n * },\n * ...\n * ]\n * }\n * ]\n *\n * @type {Array}\n * @ignore\n */\nvar __apiStruct = [];\n\n\n/**\n * `Array.prototype` reference.\n *\n * @type object\n * @ignore\n */\nvar __arrayProto = Array.prototype;\n\n\n/**\n * Abstraction for `context` parameter of the `Api` constructor to allow it to\n * take several different forms for ease of use.\n *\n * Each of the input parameter types will be converted to a DataTables settings\n * object where possible.\n *\n * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one\n * of:\n *\n * * `string` - jQuery selector. Any DataTables' matching the given selector\n * with be found and used.\n * * `node` - `TABLE` node which has already been formed into a DataTable.\n * * `jQuery` - A jQuery object of `TABLE` nodes.\n * * `object` - DataTables settings object\n * * `DataTables.Api` - API instance\n * @return {array|null} Matching DataTables settings objects. `null` or\n * `undefined` is returned if no matching DataTable is found.\n * @ignore\n */\nvar _toSettings = function ( mixed )\n{\n\tvar idx, jq;\n\tvar settings = DataTable.settings;\n\tvar tables = $.map( settings, function (el, i) {\n\t\treturn el.nTable;\n\t} );\n\n\tif ( ! mixed ) {\n\t\treturn [];\n\t}\n\telse if ( mixed.nTable && mixed.oApi ) {\n\t\t// DataTables settings object\n\t\treturn [ mixed ];\n\t}\n\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\n\t\t// Table node\n\t\tidx = $.inArray( mixed, tables );\n\t\treturn idx !== -1 ? [ settings[idx] ] : null;\n\t}\n\telse if ( mixed && typeof mixed.settings === 'function' ) {\n\t\treturn mixed.settings().toArray();\n\t}\n\telse if ( typeof mixed === 'string' ) {\n\t\t// jQuery selector\n\t\tjq = $(mixed);\n\t}\n\telse if ( mixed instanceof $ ) {\n\t\t// jQuery object (also DataTables instance)\n\t\tjq = mixed;\n\t}\n\n\tif ( jq ) {\n\t\treturn jq.map( function(i) {\n\t\t\tidx = $.inArray( this, tables );\n\t\t\treturn idx !== -1 ? settings[idx] : null;\n\t\t} ).toArray();\n\t}\n};\n\n\n/**\n * DataTables API class - used to control and interface with one or more\n * DataTables enhanced tables.\n *\n * The API class is heavily based on jQuery, presenting a chainable interface\n * that you can use to interact with tables. Each instance of the API class has\n * a \"context\" - i.e. the tables that it will operate on. This could be a single\n * table, all tables on a page or a sub-set thereof.\n *\n * Additionally the API is designed to allow you to easily work with the data in\n * the tables, retrieving and manipulating it as required. This is done by\n * presenting the API class as an array like interface. The contents of the\n * array depend upon the actions requested by each method (for example\n * `rows().nodes()` will return an array of nodes, while `rows().data()` will\n * return an array of objects or arrays depending upon your table's\n * configuration). The API object has a number of array like methods (`push`,\n * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\n * `unique` etc) to assist your working with the data held in a table.\n *\n * Most methods (those which return an Api instance) are chainable, which means\n * the return from a method call also has all of the methods available that the\n * top level object had. For example, these two calls are equivalent:\n *\n * // Not chained\n * api.row.add( {...} );\n * api.draw();\n *\n * // Chained\n * api.row.add( {...} ).draw();\n *\n * @class DataTable.Api\n * @param {array|object|string|jQuery} context DataTable identifier. This is\n * used to define which DataTables enhanced tables this API will operate on.\n * Can be one of:\n *\n * * `string` - jQuery selector. Any DataTables' matching the given selector\n * with be found and used.\n * * `node` - `TABLE` node which has already been formed into a DataTable.\n * * `jQuery` - A jQuery object of `TABLE` nodes.\n * * `object` - DataTables settings object\n * @param {array} [data] Data to initialise the Api instance with.\n *\n * @example\n * // Direct initialisation during DataTables construction\n * var api = $('#example').DataTable();\n *\n * @example\n * // Initialisation using a DataTables jQuery object\n * var api = $('#example').dataTable().api();\n *\n * @example\n * // Initialisation as a constructor\n * var api = new $.fn.DataTable.Api( 'table.dataTable' );\n */\n_Api = function ( context, data )\n{\n\tif ( ! (this instanceof _Api) ) {\n\t\treturn new _Api( context, data );\n\t}\n\n\tvar settings = [];\n\tvar ctxSettings = function ( o ) {\n\t\tvar a = _toSettings( o );\n\t\tif ( a ) {\n\t\t\tsettings.push.apply( settings, a );\n\t\t}\n\t};\n\n\tif ( Array.isArray( context ) ) {\n\t\tfor ( var i=0, ien=context.length ; i idx ?\n\t\t\tnew _Api( ctx[idx], this[idx] ) :\n\t\t\tnull;\n\t},\n\n\n\tfilter: function ( fn )\n\t{\n\t\tvar a = [];\n\n\t\tif ( __arrayProto.filter ) {\n\t\t\ta = __arrayProto.filter.call( this, fn, this );\n\t\t}\n\t\telse {\n\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\tfor ( var i=0, ien=this.length ; i 0 ) {\n\t\treturn ctx[0].json;\n\t}\n\n\t// else return undefined;\n} );\n\n\n/**\n * Get the data submitted in the last Ajax request\n */\n_api_register( 'ajax.params()', function () {\n\tvar ctx = this.context;\n\n\tif ( ctx.length > 0 ) {\n\t\treturn ctx[0].oAjaxData;\n\t}\n\n\t// else return undefined;\n} );\n\n\n/**\n * Reload tables from the Ajax data source. Note that this function will\n * automatically re-draw the table when the remote data has been loaded.\n *\n * @param {boolean} [reset=true] Reset (default) or hold the current paging\n * position. A full re-sort and re-filter is performed when this method is\n * called, which is why the pagination reset is the default action.\n * @returns {DataTables.Api} this\n */\n_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\n\treturn this.iterator( 'table', function (settings) {\n\t\t__reload( settings, resetPaging===false, callback );\n\t} );\n} );\n\n\n/**\n * Get the current Ajax URL. Note that this returns the URL from the first\n * table in the current context.\n *\n * @return {string} Current Ajax source URL\n *//**\n * Set the Ajax URL. Note that this will set the URL for all tables in the\n * current context.\n *\n * @param {string} url URL to set.\n * @returns {DataTables.Api} this\n */\n_api_register( 'ajax.url()', function ( url ) {\n\tvar ctx = this.context;\n\n\tif ( url === undefined ) {\n\t\t// get\n\t\tif ( ctx.length === 0 ) {\n\t\t\treturn undefined;\n\t\t}\n\t\tctx = ctx[0];\n\n\t\treturn ctx.ajax ?\n\t\t\t$.isPlainObject( ctx.ajax ) ?\n\t\t\t\tctx.ajax.url :\n\t\t\t\tctx.ajax :\n\t\t\tctx.sAjaxSource;\n\t}\n\n\t// set\n\treturn this.iterator( 'table', function ( settings ) {\n\t\tif ( $.isPlainObject( settings.ajax ) ) {\n\t\t\tsettings.ajax.url = url;\n\t\t}\n\t\telse {\n\t\t\tsettings.ajax = url;\n\t\t}\n\t\t// No need to consider sAjaxSource here since DataTables gives priority\n\t\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\n\t\t// value of `sAjaxSource` redundant.\n\t} );\n} );\n\n\n/**\n * Load data from the newly set Ajax URL. Note that this method is only\n * available when `ajax.url()` is used to set a URL. Additionally, this method\n * has the same effect as calling `ajax.reload()` but is provided for\n * convenience when setting a new URL. Like `ajax.reload()` it will\n * automatically redraw the table once the remote data has been loaded.\n *\n * @returns {DataTables.Api} this\n */\n_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\n\t// Same as a reload, but makes sense to present it for easy access after a\n\t// url change\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\t__reload( ctx, resetPaging===false, callback );\n\t} );\n} );\n\n\n\n\nvar _selector_run = function ( type, selector, selectFn, settings, opts )\n{\n\tvar\n\t\tout = [], res,\n\t\ta, i, ien, j, jen,\n\t\tselectorType = typeof selector;\n\n\t// Can't just check for isArray here, as an API or jQuery instance might be\n\t// given with their array like look\n\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\n\t\tselector = [ selector ];\n\t}\n\n\tfor ( i=0, ien=selector.length ; i 0 ) {\n\t\t\t// Assign the first element to the first item in the instance\n\t\t\t// and truncate the instance and context\n\t\t\tinst[0] = inst[i];\n\t\t\tinst[0].length = 1;\n\t\t\tinst.length = 1;\n\t\t\tinst.context = [ inst.context[i] ];\n\n\t\t\treturn inst;\n\t\t}\n\t}\n\n\t// Not found - return an empty instance\n\tinst.length = 0;\n\treturn inst;\n};\n\n\nvar _selector_row_indexes = function ( settings, opts )\n{\n\tvar\n\t\ti, ien, tmp, a=[],\n\t\tdisplayFiltered = settings.aiDisplay,\n\t\tdisplayMaster = settings.aiDisplayMaster;\n\n\tvar\n\t\tsearch = opts.search, // none, applied, removed\n\t\torder = opts.order, // applied, current, index (original - compatibility with 1.9)\n\t\tpage = opts.page; // all, current\n\n\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t// In server-side processing mode, most options are irrelevant since\n\t\t// rows not shown don't exist and the index order is the applied order\n\t\t// Removed is a special case - for consistency just return an empty\n\t\t// array\n\t\treturn search === 'removed' ?\n\t\t\t[] :\n\t\t\t_range( 0, displayMaster.length );\n\t}\n\telse if ( page == 'current' ) {\n\t\t// Current page implies that order=current and filter=applied, since it is\n\t\t// fairly senseless otherwise, regardless of what order and search actually\n\t\t// are\n\t\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i= 0 && search == 'applied') )\n\t\t\t\t{\n\t\t\t\t\ta.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a;\n};\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Rows\n *\n * {} - no selector - use all available rows\n * {integer} - row aoData index\n * {node} - TR node\n * {string} - jQuery selector to apply to the TR elements\n * {array} - jQuery array of nodes, or simply an array of TR nodes\n *\n */\nvar __row_selector = function ( settings, selector, opts )\n{\n\tvar rows;\n\tvar run = function ( sel ) {\n\t\tvar selInt = _intVal( sel );\n\t\tvar i, ien;\n\t\tvar aoData = settings.aoData;\n\n\t\t// Short cut - selector is a number and no options provided (default is\n\t\t// all records, so no need to check if the index is in there, since it\n\t\t// must be - dev error if the index doesn't exist).\n\t\tif ( selInt !== null && ! opts ) {\n\t\t\treturn [ selInt ];\n\t\t}\n\n\t\tif ( ! rows ) {\n\t\t\trows = _selector_row_indexes( settings, opts );\n\t\t}\n\n\t\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\n\t\t\t// Selector - integer\n\t\t\treturn [ selInt ];\n\t\t}\n\t\telse if ( sel === null || sel === undefined || sel === '' ) {\n\t\t\t// Selector - none\n\t\t\treturn rows;\n\t\t}\n\n\t\t// Selector - function\n\t\tif ( typeof sel === 'function' ) {\n\t\t\treturn $.map( rows, function (idx) {\n\t\t\t\tvar row = aoData[ idx ];\n\t\t\t\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\n\t\t\t} );\n\t\t}\n\n\t\t// Selector - node\n\t\tif ( sel.nodeName ) {\n\t\t\tvar rowIdx = sel._DT_RowIndex; // Property added by DT for fast lookup\n\t\t\tvar cellIdx = sel._DT_CellIndex;\n\n\t\t\tif ( rowIdx !== undefined ) {\n\t\t\t\t// Make sure that the row is actually still present in the table\n\t\t\t\treturn aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?\n\t\t\t\t\t[ rowIdx ] :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t\telse if ( cellIdx ) {\n\t\t\t\treturn aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?\n\t\t\t\t\t[ cellIdx.row ] :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvar host = $(sel).closest('*[data-dt-row]');\n\t\t\t\treturn host.length ?\n\t\t\t\t\t[ host.data('dt-row') ] :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t}\n\n\t\t// ID selector. Want to always be able to select rows by id, regardless\n\t\t// of if the tr element has been created or not, so can't rely upon\n\t\t// jQuery here - hence a custom implementation. This does not match\n\t\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\n\t\t// but to select it using a CSS selector engine (like Sizzle or\n\t\t// querySelect) it would need to need to be escaped for some characters.\n\t\t// DataTables simplifies this for row selectors since you can select\n\t\t// only a row. A # indicates an id any anything that follows is the id -\n\t\t// unescaped.\n\t\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\n\t\t\t// get row index from id\n\t\t\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\n\t\t\tif ( rowObj !== undefined ) {\n\t\t\t\treturn [ rowObj.idx ];\n\t\t\t}\n\n\t\t\t// need to fall through to jQuery in case there is DOM id that\n\t\t\t// matches\n\t\t}\n\t\t\n\t\t// Get nodes in the order from the `rows` array with null values removed\n\t\tvar nodes = _removeEmpty(\n\t\t\t_pluck_order( settings.aoData, rows, 'nTr' )\n\t\t);\n\n\t\t// Selector - jQuery selector string, array of nodes or jQuery object/\n\t\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\n\t\t// it also allows arrays, so this will cope with all three options\n\t\treturn $(nodes)\n\t\t\t.filter( sel )\n\t\t\t.map( function () {\n\t\t\t\treturn this._DT_RowIndex;\n\t\t\t} )\n\t\t\t.toArray();\n\t};\n\n\treturn _selector_run( 'row', selector, run, settings, opts );\n};\n\n\n_api_register( 'rows()', function ( selector, opts ) {\n\t// argument shifting\n\tif ( selector === undefined ) {\n\t\tselector = '';\n\t}\n\telse if ( $.isPlainObject( selector ) ) {\n\t\topts = selector;\n\t\tselector = '';\n\t}\n\n\topts = _selector_opts( opts );\n\n\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\treturn __row_selector( settings, selector, opts );\n\t}, 1 );\n\n\t// Want argument shifting here and in __row_selector?\n\tinst.selector.rows = selector;\n\tinst.selector.opts = opts;\n\n\treturn inst;\n} );\n\n_api_register( 'rows().nodes()', function () {\n\treturn this.iterator( 'row', function ( settings, row ) {\n\t\treturn settings.aoData[ row ].nTr || undefined;\n\t}, 1 );\n} );\n\n_api_register( 'rows().data()', function () {\n\treturn this.iterator( true, 'rows', function ( settings, rows ) {\n\t\treturn _pluck_order( settings.aoData, rows, '_aData' );\n\t}, 1 );\n} );\n\n_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\n\treturn this.iterator( 'row', function ( settings, row ) {\n\t\tvar r = settings.aoData[ row ];\n\t\treturn type === 'search' ? r._aFilterData : r._aSortData;\n\t}, 1 );\n} );\n\n_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\n\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t_fnInvalidate( settings, row, src );\n\t} );\n} );\n\n_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\n\treturn this.iterator( 'row', function ( settings, row ) {\n\t\treturn row;\n\t}, 1 );\n} );\n\n_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\n\tvar a = [];\n\tvar context = this.context;\n\n\t// `iterator` will drop undefined values, but in this case we want them\n\tfor ( var i=0, ien=context.length ; i 0 ) {\n\t\t\tsettings._iRecordsDisplay--;\n\t\t}\n\n\t\t// Check for an 'overflow' they case for displaying the table\n\t\t_fnLengthOverflow( settings );\n\n\t\t// Remove the row's ID reference if there is one\n\t\tvar id = settings.rowIdFn( rowData._aData );\n\t\tif ( id !== undefined ) {\n\t\t\tdelete settings.aIds[ id ];\n\t\t}\n\t} );\n\n\tthis.iterator( 'table', function ( settings ) {\n\t\tfor ( var i=0, ien=settings.aoData.length ; i
').addClass( k );\n\t\t\t$('td', created)\n\t\t\t\t.addClass( k )\n\t\t\t\t.html( r )\n\t\t\t\t[0].colSpan = _fnVisbleColumns( ctx );\n\n\t\t\trows.push( created[0] );\n\t\t}\n\t};\n\n\taddRow( data, klass );\n\n\tif ( row._details ) {\n\t\trow._details.detach();\n\t}\n\n\trow._details = $(rows);\n\n\t// If the children were already shown, that state should be retained\n\tif ( row._detailsShow ) {\n\t\trow._details.insertAfter( row.nTr );\n\t}\n};\n\n\n// Make state saving of child row details async to allow them to be batch processed\nvar __details_state = DataTable.util.throttle(\n\tfunction (ctx) {\n\t\t_fnSaveState( ctx[0] )\n\t},\n\t500\n);\n\n\nvar __details_remove = function ( api, idx )\n{\n\tvar ctx = api.context;\n\n\tif ( ctx.length ) {\n\t\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\n\n\t\tif ( row && row._details ) {\n\t\t\trow._details.remove();\n\n\t\t\trow._detailsShow = undefined;\n\t\t\trow._details = undefined;\n\t\t\t$( row.nTr ).removeClass( 'dt-hasChild' );\n\t\t\t__details_state( ctx );\n\t\t}\n\t}\n};\n\n\nvar __details_display = function ( api, show ) {\n\tvar ctx = api.context;\n\n\tif ( ctx.length && api.length ) {\n\t\tvar row = ctx[0].aoData[ api[0] ];\n\n\t\tif ( row._details ) {\n\t\t\trow._detailsShow = show;\n\n\t\t\tif ( show ) {\n\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t$( row.nTr ).addClass( 'dt-hasChild' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\trow._details.detach();\n\t\t\t\t$( row.nTr ).removeClass( 'dt-hasChild' );\n\t\t\t}\n\n\t\t\t_fnCallbackFire( ctx[0], null, 'childRow', [ show, api.row( api[0] ) ] )\n\n\t\t\t__details_events( ctx[0] );\n\t\t\t__details_state( ctx );\n\t\t}\n\t}\n};\n\n\nvar __details_events = function ( settings )\n{\n\tvar api = new _Api( settings );\n\tvar namespace = '.dt.DT_details';\n\tvar drawEvent = 'draw'+namespace;\n\tvar colvisEvent = 'column-sizing'+namespace;\n\tvar destroyEvent = 'destroy'+namespace;\n\tvar data = settings.aoData;\n\n\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\n\n\tif ( _pluck( data, '_details' ).length > 0 ) {\n\t\t// On each draw, insert the required elements into the document\n\t\tapi.on( drawEvent, function ( e, ctx ) {\n\t\t\tif ( settings !== ctx ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\n\t\t\t\t// Internal data grab\n\t\t\t\tvar row = data[ idx ];\n\n\t\t\t\tif ( row._detailsShow ) {\n\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\n\t\t// Column visibility change - update the colspan\n\t\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\n\t\t\tif ( settings !== ctx ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Update the colspan for the details rows (note, only if it already has\n\t\t\t// a colspan)\n\t\t\tvar row, visible = _fnVisbleColumns( ctx );\n\n\t\t\tfor ( var i=0, ien=data.length ; i=0 count from left, <0 count from right)\n * \"{integer}:visIdx\" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)\n * \"{integer}:visible\" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)\n * \"{string}:name\" - column name\n * \"{string}\" - jQuery selector on column header nodes\n *\n */\n\n// can be an array of these items, comma separated list, or an array of comma\n// separated lists\n\nvar __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;\n\n\n// r1 and r2 are redundant - but it means that the parameters match for the\n// iterator callback in columns().data()\nvar __columnData = function ( settings, column, r1, r2, rows ) {\n\tvar a = [];\n\tfor ( var row=0, ien=rows.length ; row= 0 ?\n\t\t\t\tselInt : // Count from left\n\t\t\t\tcolumns.length + selInt // Count from right (+ because its a negative value)\n\t\t\t];\n\t\t}\n\n\t\t// Selector = function\n\t\tif ( typeof s === 'function' ) {\n\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\n\t\t\treturn $.map( columns, function (col, idx) {\n\t\t\t\treturn s(\n\t\t\t\t\t\tidx,\n\t\t\t\t\t\t__columnData( settings, idx, 0, 0, rows ),\n\t\t\t\t\t\tnodes[ idx ]\n\t\t\t\t\t) ? idx : null;\n\t\t\t} );\n\t\t}\n\n\t\t// jQuery or string selector\n\t\tvar match = typeof s === 'string' ?\n\t\t\ts.match( __re_column_selector ) :\n\t\t\t'';\n\n\t\tif ( match ) {\n\t\t\tswitch( match[2] ) {\n\t\t\t\tcase 'visIdx':\n\t\t\t\tcase 'visible':\n\t\t\t\t\tvar idx = parseInt( match[1], 10 );\n\t\t\t\t\t// Visible index given, convert to column index\n\t\t\t\t\tif ( idx < 0 ) {\n\t\t\t\t\t\t// Counting from the right\n\t\t\t\t\t\tvar visColumns = $.map( columns, function (col,i) {\n\t\t\t\t\t\t\treturn col.bVisible ? i : null;\n\t\t\t\t\t\t} );\n\t\t\t\t\t\treturn [ visColumns[ visColumns.length + idx ] ];\n\t\t\t\t\t}\n\t\t\t\t\t// Counting from the left\n\t\t\t\t\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\n\n\t\t\t\tcase 'name':\n\t\t\t\t\t// match by name. `names` is column index complete and in order\n\t\t\t\t\treturn $.map( names, function (name, i) {\n\t\t\t\t\t\treturn name === match[1] ? i : null;\n\t\t\t\t\t} );\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\n\t\t// Cell in the table body\n\t\tif ( s.nodeName && s._DT_CellIndex ) {\n\t\t\treturn [ s._DT_CellIndex.column ];\n\t\t}\n\n\t\t// jQuery selector on the TH elements for the columns\n\t\tvar jqResult = $( nodes )\n\t\t\t.filter( s )\n\t\t\t.map( function () {\n\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n\t\t\t} )\n\t\t\t.toArray();\n\n\t\tif ( jqResult.length || ! s.nodeName ) {\n\t\t\treturn jqResult;\n\t\t}\n\n\t\t// Otherwise a node which might have a `dt-column` data attribute, or be\n\t\t// a child or such an element\n\t\tvar host = $(s).closest('*[data-dt-column]');\n\t\treturn host.length ?\n\t\t\t[ host.data('dt-column') ] :\n\t\t\t[];\n\t};\n\n\treturn _selector_run( 'column', selector, run, settings, opts );\n};\n\n\nvar __setColumnVis = function ( settings, column, vis ) {\n\tvar\n\t\tcols = settings.aoColumns,\n\t\tcol = cols[ column ],\n\t\tdata = settings.aoData,\n\t\trow, cells, i, ien, tr;\n\n\t// Get\n\tif ( vis === undefined ) {\n\t\treturn col.bVisible;\n\t}\n\n\t// Set\n\t// No change\n\tif ( col.bVisible === vis ) {\n\t\treturn;\n\t}\n\n\tif ( vis ) {\n\t\t// Insert column\n\t\t// Need to decide if we should use appendChild or insertBefore\n\t\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\n\n\t\tfor ( i=0, ien=data.length ; i iThat;\n\t}\n\n\treturn true;\n};\n\n\n/**\n * Check if a `
` node is a DataTable table already or not.\n *\n * @param {node|jquery|string} table Table node, jQuery object or jQuery\n * selector for the table to test. Note that if more than more than one\n * table is passed on, only the first will be checked\n * @returns {boolean} true the table given is a DataTable, or false otherwise\n * @static\n * @dtopt API-Static\n *\n * @example\n * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\n * $('#example').dataTable();\n * }\n */\nDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\n{\n\tvar t = $(table).get(0);\n\tvar is = false;\n\n\tif ( table instanceof DataTable.Api ) {\n\t\treturn true;\n\t}\n\n\t$.each( DataTable.settings, function (i, o) {\n\t\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\n\t\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\n\n\t\tif ( o.nTable === t || head === t || foot === t ) {\n\t\t\tis = true;\n\t\t}\n\t} );\n\n\treturn is;\n};\n\n\n/**\n * Get all DataTable tables that have been initialised - optionally you can\n * select to get only currently visible tables.\n *\n * @param {boolean} [visible=false] Flag to indicate if you want all (default)\n * or visible tables only.\n * @returns {array} Array of `table` nodes (not DataTable instances) which are\n * DataTables\n * @static\n * @dtopt API-Static\n *\n * @example\n * $.each( $.fn.dataTable.tables(true), function () {\n * $(table).DataTable().columns.adjust();\n * } );\n */\nDataTable.tables = DataTable.fnTables = function ( visible )\n{\n\tvar api = false;\n\n\tif ( $.isPlainObject( visible ) ) {\n\t\tapi = visible.api;\n\t\tvisible = visible.visible;\n\t}\n\n\tvar a = $.map( DataTable.settings, function (o) {\n\t\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\n\t\t\treturn o.nTable;\n\t\t}\n\t} );\n\n\treturn api ?\n\t\tnew _Api( a ) :\n\t\ta;\n};\n\n\n/**\n * Convert from camel case parameters to Hungarian notation. This is made public\n * for the extensions to provide the same ability as DataTables core to accept\n * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\n * parameters.\n *\n * @param {object} src The model object which holds all parameters that can be\n * mapped.\n * @param {object} user The object to convert from camel case to Hungarian.\n * @param {boolean} force When set to `true`, properties which already have a\n * Hungarian value in the `user` object will be overwritten. Otherwise they\n * won't be.\n */\nDataTable.camelToHungarian = _fnCamelToHungarian;\n\n\n\n/**\n *\n */\n_api_register( '$()', function ( selector, opts ) {\n\tvar\n\t\trows = this.rows( opts ).nodes(), // Get all rows\n\t\tjqRows = $(rows);\n\n\treturn $( [].concat(\n\t\tjqRows.filter( selector ).toArray(),\n\t\tjqRows.find( selector ).toArray()\n\t) );\n} );\n\n\n// jQuery functions to operate on the tables\n$.each( [ 'on', 'one', 'off' ], function (i, key) {\n\t_api_register( key+'()', function ( /* event, handler */ ) {\n\t\tvar args = Array.prototype.slice.call(arguments);\n\n\t\t// Add the `dt` namespace automatically if it isn't already present\n\t\targs[0] = $.map( args[0].split( /\\s/ ), function ( e ) {\n\t\t\treturn ! e.match(/\\.dt\\b/) ?\n\t\t\t\te+'.dt' :\n\t\t\t\te;\n\t\t\t} ).join( ' ' );\n\n\t\tvar inst = $( this.tables().nodes() );\n\t\tinst[key].apply( inst, args );\n\t\treturn this;\n\t} );\n} );\n\n\n_api_register( 'clear()', function () {\n\treturn this.iterator( 'table', function ( settings ) {\n\t\t_fnClearTable( settings );\n\t} );\n} );\n\n\n_api_register( 'settings()', function () {\n\treturn new _Api( this.context, this.context );\n} );\n\n\n_api_register( 'init()', function () {\n\tvar ctx = this.context;\n\treturn ctx.length ? ctx[0].oInit : null;\n} );\n\n\n_api_register( 'data()', function () {\n\treturn this.iterator( 'table', function ( settings ) {\n\t\treturn _pluck( settings.aoData, '_aData' );\n\t} ).flatten();\n} );\n\n\n_api_register( 'destroy()', function ( remove ) {\n\tremove = remove || false;\n\n\treturn this.iterator( 'table', function ( settings ) {\n\t\tvar classes = settings.oClasses;\n\t\tvar table = settings.nTable;\n\t\tvar tbody = settings.nTBody;\n\t\tvar thead = settings.nTHead;\n\t\tvar tfoot = settings.nTFoot;\n\t\tvar jqTable = $(table);\n\t\tvar jqTbody = $(tbody);\n\t\tvar jqWrapper = $(settings.nTableWrapper);\n\t\tvar rows = $.map( settings.aoData, function (r) { return r.nTr; } );\n\t\tvar i, ien;\n\n\t\t// Flag to note that the table is currently being destroyed - no action\n\t\t// should be taken\n\t\tsettings.bDestroying = true;\n\n\t\t// Fire off the destroy callbacks for plug-ins etc\n\t\t_fnCallbackFire( settings, \"aoDestroyCallback\", \"destroy\", [settings] );\n\n\t\t// If not being removed from the document, make all columns visible\n\t\tif ( ! remove ) {\n\t\t\tnew _Api( settings ).columns().visible( true );\n\t\t}\n\n\t\t// Blitz all `DT` namespaced events (these are internal events, the\n\t\t// lowercase, `dt` events are user subscribed and they are responsible\n\t\t// for removing them\n\t\tjqWrapper.off('.DT').find(':not(tbody *)').off('.DT');\n\t\t$(window).off('.DT-'+settings.sInstance);\n\n\t\t// When scrolling we had to break the table up - restore it\n\t\tif ( table != thead.parentNode ) {\n\t\t\tjqTable.children('thead').detach();\n\t\t\tjqTable.append( thead );\n\t\t}\n\n\t\tif ( tfoot && table != tfoot.parentNode ) {\n\t\t\tjqTable.children('tfoot').detach();\n\t\t\tjqTable.append( tfoot );\n\t\t}\n\n\t\tsettings.aaSorting = [];\n\t\tsettings.aaSortingFixed = [];\n\t\t_fnSortingClasses( settings );\n\n\t\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\n\n\t\t$('th, td', thead).removeClass( classes.sSortable+' '+\n\t\t\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\n\t\t);\n\n\t\t// Add the TR elements back into the table in their original order\n\t\tjqTbody.children().detach();\n\t\tjqTbody.append( rows );\n\n\t\tvar orig = settings.nTableWrapper.parentNode;\n\n\t\t// Remove the DataTables generated nodes, events and classes\n\t\tvar removedMethod = remove ? 'remove' : 'detach';\n\t\tjqTable[ removedMethod ]();\n\t\tjqWrapper[ removedMethod ]();\n\n\t\t// If we need to reattach the table to the document\n\t\tif ( ! remove && orig ) {\n\t\t\t// insertBefore acts like appendChild if !arg[1]\n\t\t\torig.insertBefore( table, settings.nTableReinsertBefore );\n\n\t\t\t// Restore the width of the original table - was read from the style property,\n\t\t\t// so we can restore directly to that\n\t\t\tjqTable\n\t\t\t\t.css( 'width', settings.sDestroyWidth )\n\t\t\t\t.removeClass( classes.sTable );\n\n\t\t\t// If the were originally stripe classes - then we add them back here.\n\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n\t\t\t// classes - but it's a good effort without getting carried away\n\t\t\tien = settings.asDestroyStripes.length;\n\n\t\t\tif ( ien ) {\n\t\t\t\tjqTbody.children().each( function (i) {\n\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\t/* Remove the settings object from the settings array */\n\t\tvar idx = $.inArray( settings, DataTable.settings );\n\t\tif ( idx !== -1 ) {\n\t\t\tDataTable.settings.splice( idx, 1 );\n\t\t}\n\t} );\n} );\n\n\n// Add the `every()` method for rows, columns and cells in a compact form\n$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\n\t_api_register( type+'s().every()', function ( fn ) {\n\t\tvar opts = this.selector.opts;\n\t\tvar api = this;\n\n\t\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\n\t\t\t// Rows and columns:\n\t\t\t// arg1 - index\n\t\t\t// arg2 - table counter\n\t\t\t// arg3 - loop counter\n\t\t\t// arg4 - undefined\n\t\t\t// Cells:\n\t\t\t// arg1 - row index\n\t\t\t// arg2 - column index\n\t\t\t// arg3 - table counter\n\t\t\t// arg4 - loop counter\n\t\t\tfn.call(\n\t\t\t\tapi[ type ](\n\t\t\t\t\targ1,\n\t\t\t\t\ttype==='cell' ? arg2 : opts,\n\t\t\t\t\ttype==='cell' ? opts : undefined\n\t\t\t\t),\n\t\t\t\targ1, arg2, arg3, arg4\n\t\t\t);\n\t\t} );\n\t} );\n} );\n\n\n// i18n method for extensions to be able to use the language object from the\n// DataTable\n_api_register( 'i18n()', function ( token, def, plural ) {\n\tvar ctx = this.context[0];\n\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\n\n\tif ( resolved === undefined ) {\n\t\tresolved = def;\n\t}\n\n\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\n\t\tresolved = resolved[ plural ] !== undefined ?\n\t\t\tresolved[ plural ] :\n\t\t\tresolved._;\n\t}\n\n\treturn typeof resolved === 'string'\n\t\t? resolved.replace( '%d', plural ) // nb: plural might be undefined,\n\t\t: resolved;\n} );\n/**\n * Version string for plug-ins to check compatibility. Allowed format is\n * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\n * only for non-release builds. See https://semver.org/ for more information.\n * @member\n * @type string\n * @default Version number\n */\nDataTable.version = \"1.13.11\";\n\n/**\n * Private data store, containing all of the settings objects that are\n * created for the tables on a given page.\n *\n * Note that the `DataTable.settings` object is aliased to\n * `jQuery.fn.dataTableExt` through which it may be accessed and\n * manipulated, or `jQuery.fn.dataTable.settings`.\n * @member\n * @type array\n * @default []\n * @private\n */\nDataTable.settings = [];\n\n/**\n * Object models container, for the various models that DataTables has\n * available to it. These models define the objects that are used to hold\n * the active state and configuration of the table.\n * @namespace\n */\nDataTable.models = {};\n\n\n\n/**\n * Template object for the way in which DataTables holds information about\n * search information for the global filter and individual column filters.\n * @namespace\n */\nDataTable.models.oSearch = {\n\t/**\n\t * Flag to indicate if the filtering should be case insensitive or not\n\t * @type boolean\n\t * @default true\n\t */\n\t\"bCaseInsensitive\": true,\n\n\t/**\n\t * Applied search term\n\t * @type string\n\t * @default Empty string\n\t */\n\t\"sSearch\": \"\",\n\n\t/**\n\t * Flag to indicate if the search term should be interpreted as a\n\t * regular expression (true) or not (false) and therefore and special\n\t * regex characters escaped.\n\t * @type boolean\n\t * @default false\n\t */\n\t\"bRegex\": false,\n\n\t/**\n\t * Flag to indicate if DataTables is to use its smart filtering or not.\n\t * @type boolean\n\t * @default true\n\t */\n\t\"bSmart\": true,\n\n\t/**\n\t * Flag to indicate if DataTables should only trigger a search when\n\t * the return key is pressed.\n\t * @type boolean\n\t * @default false\n\t */\n\t\"return\": false\n};\n\n\n\n\n/**\n * Template object for the way in which DataTables holds information about\n * each individual row. This is the object format used for the settings\n * aoData array.\n * @namespace\n */\nDataTable.models.oRow = {\n\t/**\n\t * TR element for the row\n\t * @type node\n\t * @default null\n\t */\n\t\"nTr\": null,\n\n\t/**\n\t * Array of TD elements for each row. This is null until the row has been\n\t * created.\n\t * @type array nodes\n\t * @default []\n\t */\n\t\"anCells\": null,\n\n\t/**\n\t * Data object from the original data source for the row. This is either\n\t * an array if using the traditional form of DataTables, or an object if\n\t * using mData options. The exact type will depend on the passed in\n\t * data from the data source, or will be an array if using DOM a data\n\t * source.\n\t * @type array|object\n\t * @default []\n\t */\n\t\"_aData\": [],\n\n\t/**\n\t * Sorting data cache - this array is ostensibly the same length as the\n\t * number of columns (although each index is generated only as it is\n\t * needed), and holds the data that is used for sorting each column in the\n\t * row. We do this cache generation at the start of the sort in order that\n\t * the formatting of the sort data need be done only once for each cell\n\t * per sort. This array should not be read from or written to by anything\n\t * other than the master sorting methods.\n\t * @type array\n\t * @default null\n\t * @private\n\t */\n\t\"_aSortData\": null,\n\n\t/**\n\t * Per cell filtering data cache. As per the sort data cache, used to\n\t * increase the performance of the filtering in DataTables\n\t * @type array\n\t * @default null\n\t * @private\n\t */\n\t\"_aFilterData\": null,\n\n\t/**\n\t * Filtering data cache. This is the same as the cell filtering cache, but\n\t * in this case a string rather than an array. This is easily computed with\n\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\n\t * needed on every search (memory traded for performance)\n\t * @type array\n\t * @default null\n\t * @private\n\t */\n\t\"_sFilterRow\": null,\n\n\t/**\n\t * Cache of the class name that DataTables has applied to the row, so we\n\t * can quickly look at this variable rather than needing to do a DOM check\n\t * on className for the nTr property.\n\t * @type string\n\t * @default Empty string\n\t * @private\n\t */\n\t\"_sRowStripe\": \"\",\n\n\t/**\n\t * Denote if the original data source was from the DOM, or the data source\n\t * object. This is used for invalidating data, so DataTables can\n\t * automatically read data from the original source, unless uninstructed\n\t * otherwise.\n\t * @type string\n\t * @default null\n\t * @private\n\t */\n\t\"src\": null,\n\n\t/**\n\t * Index in the aoData array. This saves an indexOf lookup when we have the\n\t * object, but want to know the index\n\t * @type integer\n\t * @default -1\n\t * @private\n\t */\n\t\"idx\": -1\n};\n\n\n/**\n * Template object for the column information object in DataTables. This object\n * is held in the settings aoColumns array and contains all the information that\n * DataTables needs about each individual column.\n *\n * Note that this object is related to {@link DataTable.defaults.column}\n * but this one is the internal data store for DataTables's cache of columns.\n * It should NOT be manipulated outside of DataTables. Any configuration should\n * be done through the initialisation options.\n * @namespace\n */\nDataTable.models.oColumn = {\n\t/**\n\t * Column index. This could be worked out on-the-fly with $.inArray, but it\n\t * is faster to just hold it as a variable\n\t * @type integer\n\t * @default null\n\t */\n\t\"idx\": null,\n\n\t/**\n\t * A list of the columns that sorting should occur on when this column\n\t * is sorted. That this property is an array allows multi-column sorting\n\t * to be defined for a column (for example first name / last name columns\n\t * would benefit from this). The values are integers pointing to the\n\t * columns to be sorted on (typically it will be a single integer pointing\n\t * at itself, but that doesn't need to be the case).\n\t * @type array\n\t */\n\t\"aDataSort\": null,\n\n\t/**\n\t * Define the sorting directions that are applied to the column, in sequence\n\t * as the column is repeatedly sorted upon - i.e. the first value is used\n\t * as the sorting direction when the column if first sorted (clicked on).\n\t * Sort it again (click again) and it will move on to the next index.\n\t * Repeat until loop.\n\t * @type array\n\t */\n\t\"asSorting\": null,\n\n\t/**\n\t * Flag to indicate if the column is searchable, and thus should be included\n\t * in the filtering or not.\n\t * @type boolean\n\t */\n\t\"bSearchable\": null,\n\n\t/**\n\t * Flag to indicate if the column is sortable or not.\n\t * @type boolean\n\t */\n\t\"bSortable\": null,\n\n\t/**\n\t * Flag to indicate if the column is currently visible in the table or not\n\t * @type boolean\n\t */\n\t\"bVisible\": null,\n\n\t/**\n\t * Store for manual type assignment using the `column.type` option. This\n\t * is held in store so we can manipulate the column's `sType` property.\n\t * @type string\n\t * @default null\n\t * @private\n\t */\n\t\"_sManualType\": null,\n\n\t/**\n\t * Flag to indicate if HTML5 data attributes should be used as the data\n\t * source for filtering or sorting. True is either are.\n\t * @type boolean\n\t * @default false\n\t * @private\n\t */\n\t\"_bAttrSrc\": false,\n\n\t/**\n\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t * allowing you to modify the DOM element (add background colour for example) when the\n\t * element is available.\n\t * @type function\n\t * @param {element} nTd The TD node that has been created\n\t * @param {*} sData The Data for the cell\n\t * @param {array|object} oData The data for the whole row\n\t * @param {int} iRow The row index for the aoData data store\n\t * @default null\n\t */\n\t\"fnCreatedCell\": null,\n\n\t/**\n\t * Function to get data from a cell in a column. You should never\n\t * access data directly through _aData internally in DataTables - always use\n\t * the method attached to this property. It allows mData to function as\n\t * required. This function is automatically assigned by the column\n\t * initialisation method\n\t * @type function\n\t * @param {array|object} oData The data array/object for the array\n\t * (i.e. aoData[]._aData)\n\t * @param {string} sSpecific The specific data type you want to get -\n\t * 'display', 'type' 'filter' 'sort'\n\t * @returns {*} The data for the cell from the given row's data\n\t * @default null\n\t */\n\t\"fnGetData\": null,\n\n\t/**\n\t * Function to set data for a cell in the column. You should never\n\t * set the data directly to _aData internally in DataTables - always use\n\t * this method. It allows mData to function as required. This function\n\t * is automatically assigned by the column initialisation method\n\t * @type function\n\t * @param {array|object} oData The data array/object for the array\n\t * (i.e. aoData[]._aData)\n\t * @param {*} sValue Value to set\n\t * @default null\n\t */\n\t\"fnSetData\": null,\n\n\t/**\n\t * Property to read the value for the cells in the column from the data\n\t * source array / object. If null, then the default content is used, if a\n\t * function is given then the return from the function is used.\n\t * @type function|int|string|null\n\t * @default null\n\t */\n\t\"mData\": null,\n\n\t/**\n\t * Partner property to mData which is used (only when defined) to get\n\t * the data - i.e. it is basically the same as mData, but without the\n\t * 'set' option, and also the data fed to it is the result from mData.\n\t * This is the rendering method to match the data method of mData.\n\t * @type function|int|string|null\n\t * @default null\n\t */\n\t\"mRender\": null,\n\n\t/**\n\t * Unique header TH/TD element for this column - this is what the sorting\n\t * listener is attached to (if sorting is enabled.)\n\t * @type node\n\t * @default null\n\t */\n\t\"nTh\": null,\n\n\t/**\n\t * Unique footer TH/TD element for this column (if there is one). Not used\n\t * in DataTables as such, but can be used for plug-ins to reference the\n\t * footer for each column.\n\t * @type node\n\t * @default null\n\t */\n\t\"nTf\": null,\n\n\t/**\n\t * The class to apply to all TD elements in the table's TBODY for the column\n\t * @type string\n\t * @default null\n\t */\n\t\"sClass\": null,\n\n\t/**\n\t * When DataTables calculates the column widths to assign to each column,\n\t * it finds the longest string in each column and then constructs a\n\t * temporary table and reads the widths from that. The problem with this\n\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t * string - thus the calculation can go wrong (doing it properly and putting\n\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t * a \"work around\" we provide this option. It will append its value to the\n\t * text that is found to be the longest string for the column - i.e. padding.\n\t * @type string\n\t */\n\t\"sContentPadding\": null,\n\n\t/**\n\t * Allows a default value to be given for a column's data, and will be used\n\t * whenever a null data source is encountered (this can be because mData\n\t * is set to null, or because the data source itself is null).\n\t * @type string\n\t * @default null\n\t */\n\t\"sDefaultContent\": null,\n\n\t/**\n\t * Name for the column, allowing reference to the column by name as well as\n\t * by index (needs a lookup to work by name).\n\t * @type string\n\t */\n\t\"sName\": null,\n\n\t/**\n\t * Custom sorting data type - defines which of the available plug-ins in\n\t * afnSortData the custom sorting will use - if any is defined.\n\t * @type string\n\t * @default std\n\t */\n\t\"sSortDataType\": 'std',\n\n\t/**\n\t * Class to be applied to the header element when sorting on this column\n\t * @type string\n\t * @default null\n\t */\n\t\"sSortingClass\": null,\n\n\t/**\n\t * Class to be applied to the header element when sorting on this column -\n\t * when jQuery UI theming is used.\n\t * @type string\n\t * @default null\n\t */\n\t\"sSortingClassJUI\": null,\n\n\t/**\n\t * Title of the column - what is seen in the TH element (nTh).\n\t * @type string\n\t */\n\t\"sTitle\": null,\n\n\t/**\n\t * Column sorting and filtering type\n\t * @type string\n\t * @default null\n\t */\n\t\"sType\": null,\n\n\t/**\n\t * Width of the column\n\t * @type string\n\t * @default null\n\t */\n\t\"sWidth\": null,\n\n\t/**\n\t * Width of the column when it was first \"encountered\"\n\t * @type string\n\t * @default null\n\t */\n\t\"sWidthOrig\": null\n};\n\n\n/*\n * Developer note: The properties of the object below are given in Hungarian\n * notation, that was used as the interface for DataTables prior to v1.10, however\n * from v1.10 onwards the primary interface is camel case. In order to avoid\n * breaking backwards compatibility utterly with this change, the Hungarian\n * version is still, internally the primary interface, but is is not documented\n * - hence the @name tags in each doc comment. This allows a Javascript function\n * to create a map from Hungarian notation to camel case (going the other direction\n * would require each property to be listed, which would add around 3K to the size\n * of DataTables, while this method is about a 0.5K hit).\n *\n * Ultimately this does pave the way for Hungarian notation to be dropped\n * completely, but that is a massive amount of work and will break current\n * installs (therefore is on-hold until v2).\n */\n\n/**\n * Initialisation options that can be given to DataTables at initialisation\n * time.\n * @namespace\n */\nDataTable.defaults = {\n\t/**\n\t * An array of data to use for the table, passed in at initialisation which\n\t * will be used in preference to any data which is already in the DOM. This is\n\t * particularly useful for constructing tables purely in Javascript, for\n\t * example with a custom Ajax call.\n\t * @type array\n\t * @default null\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.data\n\t *\n\t * @example\n\t * // Using a 2D array data source\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"data\": [\n\t * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\n\t * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\n\t * ],\n\t * \"columns\": [\n\t * { \"title\": \"Engine\" },\n\t * { \"title\": \"Browser\" },\n\t * { \"title\": \"Platform\" },\n\t * { \"title\": \"Version\" },\n\t * { \"title\": \"Grade\" }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using an array of objects as a data source (`data`)\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"data\": [\n\t * {\n\t * \"engine\": \"Trident\",\n\t * \"browser\": \"Internet Explorer 4.0\",\n\t * \"platform\": \"Win 95+\",\n\t * \"version\": 4,\n\t * \"grade\": \"X\"\n\t * },\n\t * {\n\t * \"engine\": \"Trident\",\n\t * \"browser\": \"Internet Explorer 5.0\",\n\t * \"platform\": \"Win 95+\",\n\t * \"version\": 5,\n\t * \"grade\": \"C\"\n\t * }\n\t * ],\n\t * \"columns\": [\n\t * { \"title\": \"Engine\", \"data\": \"engine\" },\n\t * { \"title\": \"Browser\", \"data\": \"browser\" },\n\t * { \"title\": \"Platform\", \"data\": \"platform\" },\n\t * { \"title\": \"Version\", \"data\": \"version\" },\n\t * { \"title\": \"Grade\", \"data\": \"grade\" }\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"aaData\": null,\n\n\n\t/**\n\t * If ordering is enabled, then DataTables will perform a first pass sort on\n\t * initialisation. You can define which column(s) the sort is performed\n\t * upon, and the sorting direction, with this variable. The `sorting` array\n\t * should contain an array for each column to be sorted initially containing\n\t * the column's index and a direction string ('asc' or 'desc').\n\t * @type array\n\t * @default [[0,'asc']]\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.order\n\t *\n\t * @example\n\t * // Sort by 3rd column first, and then 4th column\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"order\": [[2,'asc'], [3,'desc']]\n\t * } );\n\t * } );\n\t *\n\t * // No initial sorting\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"order\": []\n\t * } );\n\t * } );\n\t */\n\t\"aaSorting\": [[0,'asc']],\n\n\n\t/**\n\t * This parameter is basically identical to the `sorting` parameter, but\n\t * cannot be overridden by user interaction with the table. What this means\n\t * is that you could have a column (visible or hidden) which the sorting\n\t * will always be forced on first - any sorting after that (from the user)\n\t * will then be performed as required. This can be useful for grouping rows\n\t * together.\n\t * @type array\n\t * @default null\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.orderFixed\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"orderFixed\": [[0,'asc']]\n\t * } );\n\t * } )\n\t */\n\t\"aaSortingFixed\": [],\n\n\n\t/**\n\t * DataTables can be instructed to load data to display in the table from a\n\t * Ajax source. This option defines how that Ajax call is made and where to.\n\t *\n\t * The `ajax` property has three different modes of operation, depending on\n\t * how it is defined. These are:\n\t *\n\t * * `string` - Set the URL from where the data should be loaded from.\n\t * * `object` - Define properties for `jQuery.ajax`.\n\t * * `function` - Custom data get function\n\t *\n\t * `string`\n\t * --------\n\t *\n\t * As a string, the `ajax` property simply defines the URL from which\n\t * DataTables will load data.\n\t *\n\t * `object`\n\t * --------\n\t *\n\t * As an object, the parameters in the object are passed to\n\t * [jQuery.ajax](https://api.jquery.com/jQuery.ajax/) allowing fine control\n\t * of the Ajax request. DataTables has a number of default parameters which\n\t * you can override using this option. Please refer to the jQuery\n\t * documentation for a full description of the options available, although\n\t * the following parameters provide additional options in DataTables or\n\t * require special consideration:\n\t *\n\t * * `data` - As with jQuery, `data` can be provided as an object, but it\n\t * can also be used as a function to manipulate the data DataTables sends\n\t * to the server. The function takes a single parameter, an object of\n\t * parameters with the values that DataTables has readied for sending. An\n\t * object may be returned which will be merged into the DataTables\n\t * defaults, or you can add the items to the object that was passed in and\n\t * not return anything from the function. This supersedes `fnServerParams`\n\t * from DataTables 1.9-.\n\t *\n\t * * `dataSrc` - By default DataTables will look for the property `data` (or\n\t * `aaData` for compatibility with DataTables 1.9-) when obtaining data\n\t * from an Ajax source or for server-side processing - this parameter\n\t * allows that property to be changed. You can use Javascript dotted\n\t * object notation to get a data source for multiple levels of nesting, or\n\t * it my be used as a function. As a function it takes a single parameter,\n\t * the JSON returned from the server, which can be manipulated as\n\t * required, with the returned value being that used by DataTables as the\n\t * data source for the table. This supersedes `sAjaxDataProp` from\n\t * DataTables 1.9-.\n\t *\n\t * * `success` - Should not be overridden it is used internally in\n\t * DataTables. To manipulate / transform the data returned by the server\n\t * use `ajax.dataSrc`, or use `ajax` as a function (see below).\n\t *\n\t * `function`\n\t * ----------\n\t *\n\t * As a function, making the Ajax call is left up to yourself allowing\n\t * complete control of the Ajax request. Indeed, if desired, a method other\n\t * than Ajax could be used to obtain the required data, such as Web storage\n\t * or an AIR database.\n\t *\n\t * The function is given four parameters and no return is required. The\n\t * parameters are:\n\t *\n\t * 1. _object_ - Data to send to the server\n\t * 2. _function_ - Callback function that must be executed when the required\n\t * data has been obtained. That data should be passed into the callback\n\t * as the only parameter\n\t * 3. _object_ - DataTables settings object for the table\n\t *\n\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\n\t *\n\t * @type string|object|function\n\t * @default null\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.ajax\n\t * @since 1.10.0\n\t *\n\t * @example\n\t * // Get JSON data from a file via Ajax.\n\t * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\n\t * $('#example').dataTable( {\n\t * \"ajax\": \"data.json\"\n\t * } );\n\t *\n\t * @example\n\t * // Get JSON data from a file via Ajax, using `dataSrc` to change\n\t * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\n\t * $('#example').dataTable( {\n\t * \"ajax\": {\n\t * \"url\": \"data.json\",\n\t * \"dataSrc\": \"tableData\"\n\t * }\n\t * } );\n\t *\n\t * @example\n\t * // Get JSON data from a file via Ajax, using `dataSrc` to read data\n\t * // from a plain array rather than an array in an object\n\t * $('#example').dataTable( {\n\t * \"ajax\": {\n\t * \"url\": \"data.json\",\n\t * \"dataSrc\": \"\"\n\t * }\n\t * } );\n\t *\n\t * @example\n\t * // Manipulate the data returned from the server - add a link to data\n\t * // (note this can, should, be done using `render` for the column - this\n\t * // is just a simple example of how the data can be manipulated).\n\t * $('#example').dataTable( {\n\t * \"ajax\": {\n\t * \"url\": \"data.json\",\n\t * \"dataSrc\": function ( json ) {\n\t * for ( var i=0, ien=json.length ; iView message';\n\t * }\n\t * return json;\n\t * }\n\t * }\n\t * } );\n\t *\n\t * @example\n\t * // Add data to the request\n\t * $('#example').dataTable( {\n\t * \"ajax\": {\n\t * \"url\": \"data.json\",\n\t * \"data\": function ( d ) {\n\t * return {\n\t * \"extra_search\": $('#extra').val()\n\t * };\n\t * }\n\t * }\n\t * } );\n\t *\n\t * @example\n\t * // Send request as POST\n\t * $('#example').dataTable( {\n\t * \"ajax\": {\n\t * \"url\": \"data.json\",\n\t * \"type\": \"POST\"\n\t * }\n\t * } );\n\t *\n\t * @example\n\t * // Get the data from localStorage (could interface with a form for\n\t * // adding, editing and removing rows).\n\t * $('#example').dataTable( {\n\t * \"ajax\": function (data, callback, settings) {\n\t * callback(\n\t * JSON.parse( localStorage.getItem('dataTablesData') )\n\t * );\n\t * }\n\t * } );\n\t */\n\t\"ajax\": null,\n\n\n\t/**\n\t * This parameter allows you to readily specify the entries in the length drop\n\t * down menu that DataTables shows when pagination is enabled. It can be\n\t * either a 1D array of options which will be used for both the displayed\n\t * option and the value, or a 2D array which will use the array in the first\n\t * position as the value, and the array in the second position as the\n\t * displayed options (useful for language strings such as 'All').\n\t *\n\t * Note that the `pageLength` property will be automatically set to the\n\t * first value given in this array, unless `pageLength` is also provided.\n\t * @type array\n\t * @default [ 10, 25, 50, 100 ]\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.lengthMenu\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"lengthMenu\": [[10, 25, 50, -1], [10, 25, 50, \"All\"]]\n\t * } );\n\t * } );\n\t */\n\t\"aLengthMenu\": [ 10, 25, 50, 100 ],\n\n\n\t/**\n\t * The `columns` option in the initialisation parameter allows you to define\n\t * details about the way individual columns behave. For a full list of\n\t * column options that can be set, please see\n\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\n\t * define your columns, you must have an entry in the array for every single\n\t * column that you have in your table (these can be null if you don't which\n\t * to specify any options).\n\t * @member\n\t *\n\t * @name DataTable.defaults.column\n\t */\n\t\"aoColumns\": null,\n\n\t/**\n\t * Very similar to `columns`, `columnDefs` allows you to target a specific\n\t * column, multiple columns, or all columns, using the `targets` property of\n\t * each object in the array. This allows great flexibility when creating\n\t * tables, as the `columnDefs` arrays can be of any length, targeting the\n\t * columns you specifically want. `columnDefs` may use any of the column\n\t * options available: {@link DataTable.defaults.column}, but it _must_\n\t * have `targets` defined in each object in the array. Values in the `targets`\n\t * array may be:\n\t *
\n\t *
a string - class name will be matched on the TH for the column
\n\t *
0 or a positive integer - column index counting from the left
\n\t *
a negative integer - column index counting from the right
\n\t *
the string \"_all\" - all columns (i.e. assign a default)
\n\t *
\n\t * @member\n\t *\n\t * @name DataTable.defaults.columnDefs\n\t */\n\t\"aoColumnDefs\": null,\n\n\n\t/**\n\t * Basically the same as `search`, this parameter defines the individual column\n\t * filtering state at initialisation time. The array must be of the same size\n\t * as the number of columns, and each element be an object with the parameters\n\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\n\t * accepted and the default will be used.\n\t * @type array\n\t * @default []\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.searchCols\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"searchCols\": [\n\t * null,\n\t * { \"search\": \"My filter\" },\n\t * null,\n\t * { \"search\": \"^[0-9]\", \"escapeRegex\": false }\n\t * ]\n\t * } );\n\t * } )\n\t */\n\t\"aoSearchCols\": [],\n\n\n\t/**\n\t * An array of CSS classes that should be applied to displayed rows. This\n\t * array may be of any length, and DataTables will apply each class\n\t * sequentially, looping when required.\n\t * @type array\n\t * @default null Will take the values determined by the `oClasses.stripe*`\n\t * options\n\t *\n\t * @dtopt Option\n\t * @name DataTable.defaults.stripeClasses\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stripeClasses\": [ 'strip1', 'strip2', 'strip3' ]\n\t * } );\n\t * } )\n\t */\n\t\"asStripeClasses\": null,\n\n\n\t/**\n\t * Enable or disable automatic column width calculation. This can be disabled\n\t * as an optimisation (it takes some time to calculate the widths) if the\n\t * tables widths are passed in using `columns`.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.autoWidth\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"autoWidth\": false\n\t * } );\n\t * } );\n\t */\n\t\"bAutoWidth\": true,\n\n\n\t/**\n\t * Deferred rendering can provide DataTables with a huge speed boost when you\n\t * are using an Ajax or JS data source for the table. This option, when set to\n\t * true, will cause DataTables to defer the creation of the table elements for\n\t * each row until they are needed for a draw - saving a significant amount of\n\t * time.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.deferRender\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"ajax\": \"sources/arrays.txt\",\n\t * \"deferRender\": true\n\t * } );\n\t * } );\n\t */\n\t\"bDeferRender\": false,\n\n\n\t/**\n\t * Replace a DataTable which matches the given selector and replace it with\n\t * one which has the properties of the new initialisation object passed. If no\n\t * table matches the selector, then the new DataTable will be constructed as\n\t * per normal.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.destroy\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"srollY\": \"200px\",\n\t * \"paginate\": false\n\t * } );\n\t *\n\t * // Some time later....\n\t * $('#example').dataTable( {\n\t * \"filter\": false,\n\t * \"destroy\": true\n\t * } );\n\t * } );\n\t */\n\t\"bDestroy\": false,\n\n\n\t/**\n\t * Enable or disable filtering of data. Filtering in DataTables is \"smart\" in\n\t * that it allows the end user to input multiple words (space separated) and\n\t * will match a row containing those words, even if not in the order that was\n\t * specified (this allow matching across multiple columns). Note that if you\n\t * wish to use filtering in DataTables this must remain 'true' - to remove the\n\t * default filtering input box and retain filtering abilities, please use\n\t * {@link DataTable.defaults.dom}.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.searching\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"searching\": false\n\t * } );\n\t * } );\n\t */\n\t\"bFilter\": true,\n\n\n\t/**\n\t * Enable or disable the table information display. This shows information\n\t * about the data that is currently visible on the page, including information\n\t * about filtered data if that action is being performed.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.info\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"info\": false\n\t * } );\n\t * } );\n\t */\n\t\"bInfo\": true,\n\n\n\t/**\n\t * Allows the end user to select the size of a formatted page from a select\n\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.lengthChange\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"lengthChange\": false\n\t * } );\n\t * } );\n\t */\n\t\"bLengthChange\": true,\n\n\n\t/**\n\t * Enable or disable pagination.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.paging\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"paging\": false\n\t * } );\n\t * } );\n\t */\n\t\"bPaginate\": true,\n\n\n\t/**\n\t * Enable or disable the display of a 'processing' indicator when the table is\n\t * being processed (e.g. a sort). This is particularly useful for tables with\n\t * large amounts of data where it can take a noticeable amount of time to sort\n\t * the entries.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.processing\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"processing\": true\n\t * } );\n\t * } );\n\t */\n\t\"bProcessing\": false,\n\n\n\t/**\n\t * Retrieve the DataTables object for the given selector. Note that if the\n\t * table has already been initialised, this parameter will cause DataTables\n\t * to simply return the object that has already been set up - it will not take\n\t * account of any changes you might have made to the initialisation object\n\t * passed to DataTables (setting this parameter to true is an acknowledgement\n\t * that you understand this). `destroy` can be used to reinitialise a table if\n\t * you need.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.retrieve\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * initTable();\n\t * tableActions();\n\t * } );\n\t *\n\t * function initTable ()\n\t * {\n\t * return $('#example').dataTable( {\n\t * \"scrollY\": \"200px\",\n\t * \"paginate\": false,\n\t * \"retrieve\": true\n\t * } );\n\t * }\n\t *\n\t * function tableActions ()\n\t * {\n\t * var table = initTable();\n\t * // perform API operations with oTable\n\t * }\n\t */\n\t\"bRetrieve\": false,\n\n\n\t/**\n\t * When vertical (y) scrolling is enabled, DataTables will force the height of\n\t * the table's viewport to the given height at all times (useful for layout).\n\t * However, this can look odd when filtering data down to a small data set,\n\t * and the footer is left \"floating\" further down. This parameter (when\n\t * enabled) will cause DataTables to collapse the table's viewport down when\n\t * the result set will fit within the given Y height.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.scrollCollapse\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"scrollY\": \"200\",\n\t * \"scrollCollapse\": true\n\t * } );\n\t * } );\n\t */\n\t\"bScrollCollapse\": false,\n\n\n\t/**\n\t * Configure DataTables to use server-side processing. Note that the\n\t * `ajax` parameter must also be given in order to give DataTables a\n\t * source to obtain the required data for each draw.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Features\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.serverSide\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"serverSide\": true,\n\t * \"ajax\": \"xhr.php\"\n\t * } );\n\t * } );\n\t */\n\t\"bServerSide\": false,\n\n\n\t/**\n\t * Enable or disable sorting of columns. Sorting of individual columns can be\n\t * disabled by the `sortable` option for each column.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.ordering\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"ordering\": false\n\t * } );\n\t * } );\n\t */\n\t\"bSort\": true,\n\n\n\t/**\n\t * Enable or display DataTables' ability to sort multiple columns at the\n\t * same time (activated by shift-click by the user).\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.orderMulti\n\t *\n\t * @example\n\t * // Disable multiple column sorting ability\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"orderMulti\": false\n\t * } );\n\t * } );\n\t */\n\t\"bSortMulti\": true,\n\n\n\t/**\n\t * Allows control over whether DataTables should use the top (true) unique\n\t * cell that is found for a single column, or the bottom (false - default).\n\t * This is useful when using complex headers.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.orderCellsTop\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"orderCellsTop\": true\n\t * } );\n\t * } );\n\t */\n\t\"bSortCellsTop\": false,\n\n\n\t/**\n\t * Enable or disable the addition of the classes `sorting\\_1`, `sorting\\_2` and\n\t * `sorting\\_3` to the columns which are currently being sorted on. This is\n\t * presented as a feature switch as it can increase processing time (while\n\t * classes are removed and added) so for large data sets you might want to\n\t * turn this off.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.orderClasses\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"orderClasses\": false\n\t * } );\n\t * } );\n\t */\n\t\"bSortClasses\": true,\n\n\n\t/**\n\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\n\t * used to save table display information such as pagination information,\n\t * display length, filtering and sorting. As such when the end user reloads\n\t * the page the display display will match what thy had previously set up.\n\t *\n\t * Due to the use of `localStorage` the default state saving is not supported\n\t * in IE6 or 7. If state saving is required in those browsers, use\n\t * `stateSaveCallback` to provide a storage solution such as cookies.\n\t * @type boolean\n\t * @default false\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.stateSave\n\t *\n\t * @example\n\t * $(document).ready( function () {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true\n\t * } );\n\t * } );\n\t */\n\t\"bStateSave\": false,\n\n\n\t/**\n\t * This function is called when a TR element is created (and all TD child\n\t * elements have been inserted), or registered if using a DOM source, allowing\n\t * manipulation of the TR element (adding classes etc).\n\t * @type function\n\t * @param {node} row \"TR\" element for the current row\n\t * @param {array} data Raw data array for this row\n\t * @param {int} dataIndex The index of this row in the internal aoData array\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.createdRow\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"createdRow\": function( row, data, dataIndex ) {\n\t * // Bold the grade for all 'A' grade browsers\n\t * if ( data[4] == \"A\" )\n\t * {\n\t * $('td:eq(4)', row).html( 'A' );\n\t * }\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnCreatedRow\": null,\n\n\n\t/**\n\t * This function is called on every 'draw' event, and allows you to\n\t * dynamically modify any aspect you want about the created DOM.\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.drawCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"drawCallback\": function( settings ) {\n\t * alert( 'DataTables has redrawn the table' );\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnDrawCallback\": null,\n\n\n\t/**\n\t * Identical to fnHeaderCallback() but for the table footer this function\n\t * allows you to modify the table footer on every 'draw' event.\n\t * @type function\n\t * @param {node} foot \"TR\" element for the footer\n\t * @param {array} data Full table data (as derived from the original HTML)\n\t * @param {int} start Index for the current display starting point in the\n\t * display array\n\t * @param {int} end Index for the current display ending point in the\n\t * display array\n\t * @param {array int} display Index array to translate the visual position\n\t * to the full data array\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.footerCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"footerCallback\": function( tfoot, data, start, end, display ) {\n\t * tfoot.getElementsByTagName('th')[0].innerHTML = \"Starting index is \"+start;\n\t * }\n\t * } );\n\t * } )\n\t */\n\t\"fnFooterCallback\": null,\n\n\n\t/**\n\t * When rendering large numbers in the information element for the table\n\t * (i.e. \"Showing 1 to 10 of 57 entries\") DataTables will render large numbers\n\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\n\t * rendered as \"1,000,000\") to help readability for the end user. This\n\t * function will override the default method DataTables uses.\n\t * @type function\n\t * @member\n\t * @param {int} toFormat number to be formatted\n\t * @returns {string} formatted string for DataTables to show the number\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.formatNumber\n\t *\n\t * @example\n\t * // Format a number using a single quote for the separator (note that\n\t * // this can also be done with the language.thousands option)\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"formatNumber\": function ( toFormat ) {\n\t * return toFormat.toString().replace(\n\t * /\\B(?=(\\d{3})+(?!\\d))/g, \"'\"\n\t * );\n\t * };\n\t * } );\n\t * } );\n\t */\n\t\"fnFormatNumber\": function ( toFormat ) {\n\t\treturn toFormat.toString().replace(\n\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g,\n\t\t\tthis.oLanguage.sThousands\n\t\t);\n\t},\n\n\n\t/**\n\t * This function is called on every 'draw' event, and allows you to\n\t * dynamically modify the header row. This can be used to calculate and\n\t * display useful information about the table.\n\t * @type function\n\t * @param {node} head \"TR\" element for the header\n\t * @param {array} data Full table data (as derived from the original HTML)\n\t * @param {int} start Index for the current display starting point in the\n\t * display array\n\t * @param {int} end Index for the current display ending point in the\n\t * display array\n\t * @param {array int} display Index array to translate the visual position\n\t * to the full data array\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.headerCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"fheaderCallback\": function( head, data, start, end, display ) {\n\t * head.getElementsByTagName('th')[0].innerHTML = \"Displaying \"+(end-start)+\" records\";\n\t * }\n\t * } );\n\t * } )\n\t */\n\t\"fnHeaderCallback\": null,\n\n\n\t/**\n\t * The information element can be used to convey information about the current\n\t * state of the table. Although the internationalisation options presented by\n\t * DataTables are quite capable of dealing with most customisations, there may\n\t * be times where you wish to customise the string further. This callback\n\t * allows you to do exactly that.\n\t * @type function\n\t * @param {object} oSettings DataTables settings object\n\t * @param {int} start Starting position in data for the draw\n\t * @param {int} end End position in data for the draw\n\t * @param {int} max Total number of rows in the table (regardless of\n\t * filtering)\n\t * @param {int} total Total number of rows in the data set, after filtering\n\t * @param {string} pre The string that DataTables has formatted using it's\n\t * own rules\n\t * @returns {string} The string to be displayed in the information element.\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.infoCallback\n\t *\n\t * @example\n\t * $('#example').dataTable( {\n\t * \"infoCallback\": function( settings, start, end, max, total, pre ) {\n\t * return start +\" to \"+ end;\n\t * }\n\t * } );\n\t */\n\t\"fnInfoCallback\": null,\n\n\n\t/**\n\t * Called when the table has been initialised. Normally DataTables will\n\t * initialise sequentially and there will be no need for this function,\n\t * however, this does not hold true when using external language information\n\t * since that is obtained using an async XHR call.\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t * @param {object} json The JSON object request from the server - only\n\t * present if client-side Ajax sourced data is used\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.initComplete\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"initComplete\": function(settings, json) {\n\t * alert( 'DataTables has finished its initialisation.' );\n\t * }\n\t * } );\n\t * } )\n\t */\n\t\"fnInitComplete\": null,\n\n\n\t/**\n\t * Called at the very start of each table draw and can be used to cancel the\n\t * draw by returning false, any other return (including undefined) results in\n\t * the full draw occurring).\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t * @returns {boolean} False will cancel the draw, anything else (including no\n\t * return) will allow it to complete.\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.preDrawCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"preDrawCallback\": function( settings ) {\n\t * if ( $('#test').val() == 1 ) {\n\t * return false;\n\t * }\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnPreDrawCallback\": null,\n\n\n\t/**\n\t * This function allows you to 'post process' each row after it have been\n\t * generated for each table draw, but before it is rendered on screen. This\n\t * function might be used for setting the row class name etc.\n\t * @type function\n\t * @param {node} row \"TR\" element for the current row\n\t * @param {array} data Raw data array for this row\n\t * @param {int} displayIndex The display index for the current table draw\n\t * @param {int} displayIndexFull The index of the data in the full list of\n\t * rows (after filtering)\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.rowCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"rowCallback\": function( row, data, displayIndex, displayIndexFull ) {\n\t * // Bold the grade for all 'A' grade browsers\n\t * if ( data[4] == \"A\" ) {\n\t * $('td:eq(4)', row).html( 'A' );\n\t * }\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnRowCallback\": null,\n\n\n\t/**\n\t * __Deprecated__ The functionality provided by this parameter has now been\n\t * superseded by that provided through `ajax`, which should be used instead.\n\t *\n\t * This parameter allows you to override the default function which obtains\n\t * the data from the server so something more suitable for your application.\n\t * For example you could use POST data, or pull information from a Gears or\n\t * AIR database.\n\t * @type function\n\t * @member\n\t * @param {string} source HTTP source to obtain the data from (`ajax`)\n\t * @param {array} data A key/value pair object containing the data to send\n\t * to the server\n\t * @param {function} callback to be called on completion of the data get\n\t * process that will draw the data on the page.\n\t * @param {object} settings DataTables settings object\n\t *\n\t * @dtopt Callbacks\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.serverData\n\t *\n\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n\t */\n\t\"fnServerData\": null,\n\n\n\t/**\n\t * __Deprecated__ The functionality provided by this parameter has now been\n\t * superseded by that provided through `ajax`, which should be used instead.\n\t *\n\t * It is often useful to send extra data to the server when making an Ajax\n\t * request - for example custom filtering information, and this callback\n\t * function makes it trivial to send extra information to the server. The\n\t * passed in parameter is the data set that has been constructed by\n\t * DataTables, and you can add to this or modify it as you require.\n\t * @type function\n\t * @param {array} data Data array (array of objects which are name/value\n\t * pairs) that has been constructed by DataTables and will be sent to the\n\t * server. In the case of Ajax sourced data with server-side processing\n\t * this will be an empty array, for server-side processing there will be a\n\t * significant number of parameters!\n\t * @returns {undefined} Ensure that you modify the data array passed in,\n\t * as this is passed by reference.\n\t *\n\t * @dtopt Callbacks\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.serverParams\n\t *\n\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n\t */\n\t\"fnServerParams\": null,\n\n\n\t/**\n\t * Load the table state. With this function you can define from where, and how, the\n\t * state of a table is loaded. By default DataTables will load from `localStorage`\n\t * but you might wish to use a server-side database or cookies.\n\t * @type function\n\t * @member\n\t * @param {object} settings DataTables settings object\n\t * @param {object} callback Callback that can be executed when done. It\n\t * should be passed the loaded state object.\n\t * @return {object} The DataTables state object to be loaded\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.stateLoadCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateLoadCallback\": function (settings, callback) {\n\t * $.ajax( {\n\t * \"url\": \"/state_load\",\n\t * \"dataType\": \"json\",\n\t * \"success\": function (json) {\n\t * callback( json );\n\t * }\n\t * } );\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnStateLoadCallback\": function ( settings ) {\n\t\ttry {\n\t\t\treturn JSON.parse(\n\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\n\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname\n\t\t\t\t)\n\t\t\t);\n\t\t} catch (e) {\n\t\t\treturn {};\n\t\t}\n\t},\n\n\n\t/**\n\t * Callback which allows modification of the saved state prior to loading that state.\n\t * This callback is called when the table is loading state from the stored data, but\n\t * prior to the settings object being modified by the saved state. Note that for\n\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\n\t * a plug-in.\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t * @param {object} data The state object that is to be loaded\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.stateLoadParams\n\t *\n\t * @example\n\t * // Remove a saved filter, so filtering is never loaded\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateLoadParams\": function (settings, data) {\n\t * data.oSearch.sSearch = \"\";\n\t * }\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Disallow state loading by returning false\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateLoadParams\": function (settings, data) {\n\t * return false;\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnStateLoadParams\": null,\n\n\n\t/**\n\t * Callback that is called when the state has been loaded from the state saving method\n\t * and the DataTables settings object has been modified as a result of the loaded state.\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t * @param {object} data The state object that was loaded\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.stateLoaded\n\t *\n\t * @example\n\t * // Show an alert with the filtering value that was saved\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateLoaded\": function (settings, data) {\n\t * alert( 'Saved filter was: '+data.oSearch.sSearch );\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnStateLoaded\": null,\n\n\n\t/**\n\t * Save the table state. This function allows you to define where and how the state\n\t * information for the table is stored By default DataTables will use `localStorage`\n\t * but you might wish to use a server-side database or cookies.\n\t * @type function\n\t * @member\n\t * @param {object} settings DataTables settings object\n\t * @param {object} data The state object to be saved\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.stateSaveCallback\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateSaveCallback\": function (settings, data) {\n\t * // Send an Ajax request to the server with the state object\n\t * $.ajax( {\n\t * \"url\": \"/state_save\",\n\t * \"data\": data,\n\t * \"dataType\": \"json\",\n\t * \"method\": \"POST\"\n\t * \"success\": function () {}\n\t * } );\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnStateSaveCallback\": function ( settings, data ) {\n\t\ttry {\n\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\n\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname,\n\t\t\t\tJSON.stringify( data )\n\t\t\t);\n\t\t} catch (e) {}\n\t},\n\n\n\t/**\n\t * Callback which allows modification of the state to be saved. Called when the table\n\t * has changed state a new state save is required. This method allows modification of\n\t * the state saving object prior to actually doing the save, including addition or\n\t * other state properties or modification. Note that for plug-in authors, you should\n\t * use the `stateSaveParams` event to save parameters for a plug-in.\n\t * @type function\n\t * @param {object} settings DataTables settings object\n\t * @param {object} data The state object to be saved\n\t *\n\t * @dtopt Callbacks\n\t * @name DataTable.defaults.stateSaveParams\n\t *\n\t * @example\n\t * // Remove a saved filter, so filtering is never saved\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateSave\": true,\n\t * \"stateSaveParams\": function (settings, data) {\n\t * data.oSearch.sSearch = \"\";\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"fnStateSaveParams\": null,\n\n\n\t/**\n\t * Duration for which the saved state information is considered valid. After this period\n\t * has elapsed the state will be returned to the default.\n\t * Value is given in seconds.\n\t * @type int\n\t * @default 7200 (2 hours)\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.stateDuration\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"stateDuration\": 60*60*24; // 1 day\n\t * } );\n\t * } )\n\t */\n\t\"iStateDuration\": 7200,\n\n\n\t/**\n\t * When enabled DataTables will not make a request to the server for the first\n\t * page draw - rather it will use the data already on the page (no sorting etc\n\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\n\t * is used to indicate that deferred loading is required, but it is also used\n\t * to tell DataTables how many records there are in the full table (allowing\n\t * the information element and pagination to be displayed correctly). In the case\n\t * where a filtering is applied to the table on initial load, this can be\n\t * indicated by giving the parameter as an array, where the first element is\n\t * the number of records available after filtering and the second element is the\n\t * number of records without filtering (allowing the table information element\n\t * to be shown correctly).\n\t * @type int | array\n\t * @default null\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.deferLoading\n\t *\n\t * @example\n\t * // 57 records available in the table, no filtering applied\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"serverSide\": true,\n\t * \"ajax\": \"scripts/server_processing.php\",\n\t * \"deferLoading\": 57\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // 57 records after filtering, 100 without filtering (an initial filter applied)\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"serverSide\": true,\n\t * \"ajax\": \"scripts/server_processing.php\",\n\t * \"deferLoading\": [ 57, 100 ],\n\t * \"search\": {\n\t * \"search\": \"my_filter\"\n\t * }\n\t * } );\n\t * } );\n\t */\n\t\"iDeferLoading\": null,\n\n\n\t/**\n\t * Number of rows to display on a single page when using pagination. If\n\t * feature enabled (`lengthChange`) then the end user will be able to override\n\t * this to a custom setting using a pop-up menu.\n\t * @type int\n\t * @default 10\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.pageLength\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"pageLength\": 50\n\t * } );\n\t * } )\n\t */\n\t\"iDisplayLength\": 10,\n\n\n\t/**\n\t * Define the starting point for data display when using DataTables with\n\t * pagination. Note that this parameter is the number of records, rather than\n\t * the page number, so if you have 10 records per page and want to start on\n\t * the third page, it should be \"20\".\n\t * @type int\n\t * @default 0\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.displayStart\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"displayStart\": 20\n\t * } );\n\t * } )\n\t */\n\t\"iDisplayStart\": 0,\n\n\n\t/**\n\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\n\t * and filtering) by adding a `tabindex` attribute to the required elements. This\n\t * allows you to tab through the controls and press the enter key to activate them.\n\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\n\t * You can overrule this using this parameter if you wish. Use a value of -1 to\n\t * disable built-in keyboard navigation.\n\t * @type int\n\t * @default 0\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.tabIndex\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"tabIndex\": 1\n\t * } );\n\t * } );\n\t */\n\t\"iTabIndex\": 0,\n\n\n\t/**\n\t * Classes that DataTables assigns to the various components and features\n\t * that it adds to the HTML table. This allows classes to be configured\n\t * during initialisation in addition to through the static\n\t * {@link DataTable.ext.oStdClasses} object).\n\t * @namespace\n\t * @name DataTable.defaults.classes\n\t */\n\t\"oClasses\": {},\n\n\n\t/**\n\t * All strings that DataTables uses in the user interface that it creates\n\t * are defined in this object, allowing you to modified them individually or\n\t * completely replace them all as required.\n\t * @namespace\n\t * @name DataTable.defaults.language\n\t */\n\t\"oLanguage\": {\n\t\t/**\n\t\t * Strings that are used for WAI-ARIA labels and controls only (these are not\n\t\t * actually visible on the page, but will be read by screenreaders, and thus\n\t\t * must be internationalised as well).\n\t\t * @namespace\n\t\t * @name DataTable.defaults.language.aria\n\t\t */\n\t\t\"oAria\": {\n\t\t\t/**\n\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t * sorted ascending by activing the column (click or return when focused).\n\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t * @type string\n\t\t\t * @default : activate to sort column ascending\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.aria.sortAscending\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"aria\": {\n\t\t\t * \"sortAscending\": \" - click/return to sort ascending\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sSortAscending\": \": activate to sort column ascending\",\n\n\t\t\t/**\n\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t * sorted descending by activing the column (click or return when focused).\n\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t * @type string\n\t\t\t * @default : activate to sort column ascending\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.aria.sortDescending\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"aria\": {\n\t\t\t * \"sortDescending\": \" - click/return to sort descending\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sSortDescending\": \": activate to sort column descending\"\n\t\t},\n\n\t\t/**\n\t\t * Pagination string used by DataTables for the built-in pagination\n\t\t * control types.\n\t\t * @namespace\n\t\t * @name DataTable.defaults.language.paginate\n\t\t */\n\t\t\"oPaginate\": {\n\t\t\t/**\n\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t * button to take the user to the first page.\n\t\t\t * @type string\n\t\t\t * @default First\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.paginate.first\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"paginate\": {\n\t\t\t * \"first\": \"First page\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sFirst\": \"First\",\n\n\n\t\t\t/**\n\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t * button to take the user to the last page.\n\t\t\t * @type string\n\t\t\t * @default Last\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.paginate.last\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"paginate\": {\n\t\t\t * \"last\": \"Last page\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sLast\": \"Last\",\n\n\n\t\t\t/**\n\t\t\t * Text to use for the 'next' pagination button (to take the user to the\n\t\t\t * next page).\n\t\t\t * @type string\n\t\t\t * @default Next\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.paginate.next\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"paginate\": {\n\t\t\t * \"next\": \"Next page\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sNext\": \"Next\",\n\n\n\t\t\t/**\n\t\t\t * Text to use for the 'previous' pagination button (to take the user to\n\t\t\t * the previous page).\n\t\t\t * @type string\n\t\t\t * @default Previous\n\t\t\t *\n\t\t\t * @dtopt Language\n\t\t\t * @name DataTable.defaults.language.paginate.previous\n\t\t\t *\n\t\t\t * @example\n\t\t\t * $(document).ready( function() {\n\t\t\t * $('#example').dataTable( {\n\t\t\t * \"language\": {\n\t\t\t * \"paginate\": {\n\t\t\t * \"previous\": \"Previous page\"\n\t\t\t * }\n\t\t\t * }\n\t\t\t * } );\n\t\t\t * } );\n\t\t\t */\n\t\t\t\"sPrevious\": \"Previous\"\n\t\t},\n\n\t\t/**\n\t\t * This string is shown in preference to `zeroRecords` when the table is\n\t\t * empty of data (regardless of filtering). Note that this is an optional\n\t\t * parameter - if it is not given, the value of `zeroRecords` will be used\n\t\t * instead (either the default or given value).\n\t\t * @type string\n\t\t * @default No data available in table\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.emptyTable\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"emptyTable\": \"No data available in table\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sEmptyTable\": \"No data available in table\",\n\n\n\t\t/**\n\t\t * This string gives information to the end user about the information\n\t\t * that is current on display on the page. The following tokens can be\n\t\t * used in the string and will be dynamically replaced as the table\n\t\t * display updates. This tokens can be placed anywhere in the string, or\n\t\t * removed as needed by the language requires:\n\t\t *\n\t\t * * `\\_START\\_` - Display index of the first record on the current page\n\t\t * * `\\_END\\_` - Display index of the last record on the current page\n\t\t * * `\\_TOTAL\\_` - Number of records in the table after filtering\n\t\t * * `\\_MAX\\_` - Number of records in the table without filtering\n\t\t * * `\\_PAGE\\_` - Current page number\n\t\t * * `\\_PAGES\\_` - Total number of pages of data in the table\n\t\t *\n\t\t * @type string\n\t\t * @default Showing _START_ to _END_ of _TOTAL_ entries\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.info\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"info\": \"Showing page _PAGE_ of _PAGES_\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sInfo\": \"Showing _START_ to _END_ of _TOTAL_ entries\",\n\n\n\t\t/**\n\t\t * Display information string for when the table is empty. Typically the\n\t\t * format of this string should match `info`.\n\t\t * @type string\n\t\t * @default Showing 0 to 0 of 0 entries\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.infoEmpty\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"infoEmpty\": \"No entries to show\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sInfoEmpty\": \"Showing 0 to 0 of 0 entries\",\n\n\n\t\t/**\n\t\t * When a user filters the information in a table, this string is appended\n\t\t * to the information (`info`) to give an idea of how strong the filtering\n\t\t * is. The variable _MAX_ is dynamically updated.\n\t\t * @type string\n\t\t * @default (filtered from _MAX_ total entries)\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.infoFiltered\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"infoFiltered\": \" - filtering from _MAX_ records\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sInfoFiltered\": \"(filtered from _MAX_ total entries)\",\n\n\n\t\t/**\n\t\t * If can be useful to append extra information to the info string at times,\n\t\t * and this variable does exactly that. This information will be appended to\n\t\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\n\t\t * being used) at all times.\n\t\t * @type string\n\t\t * @default Empty string\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.infoPostFix\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"infoPostFix\": \"All records shown are derived from real information.\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sInfoPostFix\": \"\",\n\n\n\t\t/**\n\t\t * This decimal place operator is a little different from the other\n\t\t * language options since DataTables doesn't output floating point\n\t\t * numbers, so it won't ever use this for display of a number. Rather,\n\t\t * what this parameter does is modify the sort methods of the table so\n\t\t * that numbers which are in a format which has a character other than\n\t\t * a period (`.`) as a decimal place will be sorted numerically.\n\t\t *\n\t\t * Note that numbers with different decimal places cannot be shown in\n\t\t * the same table and still be sortable, the table must be consistent.\n\t\t * However, multiple different tables on the page can use different\n\t\t * decimal place characters.\n\t\t * @type string\n\t\t * @default \n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.decimal\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"decimal\": \",\"\n\t\t * \"thousands\": \".\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sDecimal\": \"\",\n\n\n\t\t/**\n\t\t * DataTables has a build in number formatter (`formatNumber`) which is\n\t\t * used to format large numbers that are used in the table information.\n\t\t * By default a comma is used, but this can be trivially changed to any\n\t\t * character you wish with this parameter.\n\t\t * @type string\n\t\t * @default ,\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.thousands\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"thousands\": \"'\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sThousands\": \",\",\n\n\n\t\t/**\n\t\t * Detail the action that will be taken when the drop down menu for the\n\t\t * pagination length option is changed. The '_MENU_' variable is replaced\n\t\t * with a default select list of 10, 25, 50 and 100, and can be replaced\n\t\t * with a custom select box if required.\n\t\t * @type string\n\t\t * @default Show _MENU_ entries\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.lengthMenu\n\t\t *\n\t\t * @example\n\t\t * // Language change only\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"lengthMenu\": \"Display _MENU_ records\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t *\n\t\t * @example\n\t\t * // Language and options change\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"lengthMenu\": 'Display records'\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sLengthMenu\": \"Show _MENU_ entries\",\n\n\n\t\t/**\n\t\t * When using Ajax sourced data and during the first draw when DataTables is\n\t\t * gathering the data, this message is shown in an empty row in the table to\n\t\t * indicate to the end user the the data is being loaded. Note that this\n\t\t * parameter is not used when loading data by server-side processing, just\n\t\t * Ajax sourced data with client-side processing.\n\t\t * @type string\n\t\t * @default Loading...\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.loadingRecords\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"loadingRecords\": \"Please wait - loading...\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sLoadingRecords\": \"Loading...\",\n\n\n\t\t/**\n\t\t * Text which is displayed when the table is processing a user action\n\t\t * (usually a sort command or similar).\n\t\t * @type string\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.processing\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"processing\": \"DataTables is currently busy\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sProcessing\": \"\",\n\n\n\t\t/**\n\t\t * Details the actions that will be taken when the user types into the\n\t\t * filtering input text box. The variable \"_INPUT_\", if used in the string,\n\t\t * is replaced with the HTML text box for the filtering input allowing\n\t\t * control over where it appears in the string. If \"_INPUT_\" is not given\n\t\t * then the input box is appended to the string automatically.\n\t\t * @type string\n\t\t * @default Search:\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.search\n\t\t *\n\t\t * @example\n\t\t * // Input text box will be appended at the end automatically\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"search\": \"Filter records:\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t *\n\t\t * @example\n\t\t * // Specify where the filter should appear\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"search\": \"Apply filter _INPUT_ to table\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sSearch\": \"Search:\",\n\n\n\t\t/**\n\t\t * Assign a `placeholder` attribute to the search `input` element\n\t\t * @type string\n\t\t * @default \n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.searchPlaceholder\n\t\t */\n\t\t\"sSearchPlaceholder\": \"\",\n\n\n\t\t/**\n\t\t * All of the language information can be stored in a file on the\n\t\t * server-side, which DataTables will look up if this parameter is passed.\n\t\t * It must store the URL of the language file, which is in a JSON format,\n\t\t * and the object has the same properties as the oLanguage object in the\n\t\t * initialiser object (i.e. the above parameters). Please refer to one of\n\t\t * the example language files to see how this works in action.\n\t\t * @type string\n\t\t * @default Empty string - i.e. disabled\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.url\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"url\": \"https://www.sprymedia.co.uk/dataTables/lang.txt\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sUrl\": \"\",\n\n\n\t\t/**\n\t\t * Text shown inside the table records when the is no information to be\n\t\t * displayed after filtering. `emptyTable` is shown when there is simply no\n\t\t * information in the table at all (regardless of filtering).\n\t\t * @type string\n\t\t * @default No matching records found\n\t\t *\n\t\t * @dtopt Language\n\t\t * @name DataTable.defaults.language.zeroRecords\n\t\t *\n\t\t * @example\n\t\t * $(document).ready( function() {\n\t\t * $('#example').dataTable( {\n\t\t * \"language\": {\n\t\t * \"zeroRecords\": \"No records to display\"\n\t\t * }\n\t\t * } );\n\t\t * } );\n\t\t */\n\t\t\"sZeroRecords\": \"No matching records found\"\n\t},\n\n\n\t/**\n\t * This parameter allows you to have define the global filtering state at\n\t * initialisation time. As an object the `search` parameter must be\n\t * defined, but all other parameters are optional. When `regex` is true,\n\t * the search string will be treated as a regular expression, when false\n\t * (default) it will be treated as a straight string. When `smart`\n\t * DataTables will use it's smart filtering methods (to word match at\n\t * any point in the data), when false this will not be done.\n\t * @namespace\n\t * @extends DataTable.models.oSearch\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.search\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"search\": {\"search\": \"Initial search\"}\n\t * } );\n\t * } )\n\t */\n\t\"oSearch\": $.extend( {}, DataTable.models.oSearch ),\n\n\n\t/**\n\t * __Deprecated__ The functionality provided by this parameter has now been\n\t * superseded by that provided through `ajax`, which should be used instead.\n\t *\n\t * By default DataTables will look for the property `data` (or `aaData` for\n\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\n\t * source or for server-side processing - this parameter allows that\n\t * property to be changed. You can use Javascript dotted object notation to\n\t * get a data source for multiple levels of nesting.\n\t * @type string\n\t * @default data\n\t *\n\t * @dtopt Options\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.ajaxDataProp\n\t *\n\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n\t */\n\t\"sAjaxDataProp\": \"data\",\n\n\n\t/**\n\t * __Deprecated__ The functionality provided by this parameter has now been\n\t * superseded by that provided through `ajax`, which should be used instead.\n\t *\n\t * You can instruct DataTables to load data from an external\n\t * source using this parameter (use aData if you want to pass data in you\n\t * already have). Simply provide a url a JSON object can be obtained from.\n\t * @type string\n\t * @default null\n\t *\n\t * @dtopt Options\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.ajaxSource\n\t *\n\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n\t */\n\t\"sAjaxSource\": null,\n\n\n\t/**\n\t * This initialisation variable allows you to specify exactly where in the\n\t * DOM you want DataTables to inject the various controls it adds to the page\n\t * (for example you might want the pagination controls at the top of the\n\t * table). DIV elements (with or without a custom class) can also be added to\n\t * aid styling. The follow syntax is used:\n\t *
\n\t * @type string\n\t * @default lfrtip (when `jQueryUI` is false)or\n\t * <\"H\"lfr>t<\"F\"ip> (when `jQueryUI` is true)\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.dom\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"dom\": '<\"top\"i>rt<\"bottom\"flp><\"clear\">'\n\t * } );\n\t * } );\n\t */\n\t\"sDom\": \"lfrtip\",\n\n\n\t/**\n\t * Search delay option. This will throttle full table searches that use the\n\t * DataTables provided search input element (it does not effect calls to\n\t * `dt-api search()`, providing a delay before the search is made.\n\t * @type integer\n\t * @default 0\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.searchDelay\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"searchDelay\": 200\n\t * } );\n\t * } )\n\t */\n\t\"searchDelay\": null,\n\n\n\t/**\n\t * DataTables features six different built-in options for the buttons to\n\t * display for pagination control:\n\t *\n\t * * `numbers` - Page number buttons only\n\t * * `simple` - 'Previous' and 'Next' buttons only\n\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\n\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\n\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers\n\t * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers\n\t * \n\t * Further methods can be added using {@link DataTable.ext.oPagination}.\n\t * @type string\n\t * @default simple_numbers\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.pagingType\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"pagingType\": \"full_numbers\"\n\t * } );\n\t * } )\n\t */\n\t\"sPaginationType\": \"simple_numbers\",\n\n\n\t/**\n\t * Enable horizontal scrolling. When a table is too wide to fit into a\n\t * certain layout, or you have a large number of columns in the table, you\n\t * can enable x-scrolling to show the table in a viewport, which can be\n\t * scrolled. This property can be `true` which will allow the table to\n\t * scroll horizontally when needed, or any CSS unit, or a number (in which\n\t * case it will be treated as a pixel measurement). Setting as simply `true`\n\t * is recommended.\n\t * @type boolean|string\n\t * @default blank string - i.e. disabled\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.scrollX\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"scrollX\": true,\n\t * \"scrollCollapse\": true\n\t * } );\n\t * } );\n\t */\n\t\"sScrollX\": \"\",\n\n\n\t/**\n\t * This property can be used to force a DataTable to use more width than it\n\t * might otherwise do when x-scrolling is enabled. For example if you have a\n\t * table which requires to be well spaced, this parameter is useful for\n\t * \"over-sizing\" the table, and thus forcing scrolling. This property can by\n\t * any CSS unit, or a number (in which case it will be treated as a pixel\n\t * measurement).\n\t * @type string\n\t * @default blank string - i.e. disabled\n\t *\n\t * @dtopt Options\n\t * @name DataTable.defaults.scrollXInner\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"scrollX\": \"100%\",\n\t * \"scrollXInner\": \"110%\"\n\t * } );\n\t * } );\n\t */\n\t\"sScrollXInner\": \"\",\n\n\n\t/**\n\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\n\t * to the given height, and enable scrolling for any data which overflows the\n\t * current viewport. This can be used as an alternative to paging to display\n\t * a lot of data in a small area (although paging and scrolling can both be\n\t * enabled at the same time). This property can be any CSS unit, or a number\n\t * (in which case it will be treated as a pixel measurement).\n\t * @type string\n\t * @default blank string - i.e. disabled\n\t *\n\t * @dtopt Features\n\t * @name DataTable.defaults.scrollY\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"scrollY\": \"200px\",\n\t * \"paginate\": false\n\t * } );\n\t * } );\n\t */\n\t\"sScrollY\": \"\",\n\n\n\t/**\n\t * __Deprecated__ The functionality provided by this parameter has now been\n\t * superseded by that provided through `ajax`, which should be used instead.\n\t *\n\t * Set the HTTP method that is used to make the Ajax call for server-side\n\t * processing or Ajax sourced data.\n\t * @type string\n\t * @default GET\n\t *\n\t * @dtopt Options\n\t * @dtopt Server-side\n\t * @name DataTable.defaults.serverMethod\n\t *\n\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n\t */\n\t\"sServerMethod\": \"GET\",\n\n\n\t/**\n\t * DataTables makes use of renderers when displaying HTML elements for\n\t * a table. These renderers can be added or modified by plug-ins to\n\t * generate suitable mark-up for a site. For example the Bootstrap\n\t * integration plug-in for DataTables uses a paging button renderer to\n\t * display pagination buttons in the mark-up required by Bootstrap.\n\t *\n\t * For further information about the renderers available see\n\t * DataTable.ext.renderer\n\t * @type string|object\n\t * @default null\n\t *\n\t * @name DataTable.defaults.renderer\n\t *\n\t */\n\t\"renderer\": null,\n\n\n\t/**\n\t * Set the data property name that DataTables should use to get a row's id\n\t * to set as the `id` property in the node.\n\t * @type string\n\t * @default DT_RowId\n\t *\n\t * @name DataTable.defaults.rowId\n\t */\n\t\"rowId\": \"DT_RowId\"\n};\n\n_fnHungarianMap( DataTable.defaults );\n\n\n\n/*\n * Developer note - See note in model.defaults.js about the use of Hungarian\n * notation and camel case.\n */\n\n/**\n * Column options that can be given to DataTables at initialisation time.\n * @namespace\n */\nDataTable.defaults.column = {\n\t/**\n\t * Define which column(s) an order will occur on for this column. This\n\t * allows a column's ordering to take multiple columns into account when\n\t * doing a sort or use the data from a different column. For example first\n\t * name / last name columns make sense to do a multi-column sort over the\n\t * two columns.\n\t * @type array|int\n\t * @default null Takes the value of the column index automatically\n\t *\n\t * @name DataTable.defaults.column.orderData\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"orderData\": [ 0, 1 ], \"targets\": [ 0 ] },\n\t * { \"orderData\": [ 1, 0 ], \"targets\": [ 1 ] },\n\t * { \"orderData\": 2, \"targets\": [ 2 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"orderData\": [ 0, 1 ] },\n\t * { \"orderData\": [ 1, 0 ] },\n\t * { \"orderData\": 2 },\n\t * null,\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"aDataSort\": null,\n\t\"iDataSort\": -1,\n\n\n\t/**\n\t * You can control the default ordering direction, and even alter the\n\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\n\t * using this parameter.\n\t * @type array\n\t * @default [ 'asc', 'desc' ]\n\t *\n\t * @name DataTable.defaults.column.orderSequence\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"orderSequence\": [ \"asc\" ], \"targets\": [ 1 ] },\n\t * { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ], \"targets\": [ 2 ] },\n\t * { \"orderSequence\": [ \"desc\" ], \"targets\": [ 3 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * null,\n\t * { \"orderSequence\": [ \"asc\" ] },\n\t * { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ] },\n\t * { \"orderSequence\": [ \"desc\" ] },\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"asSorting\": [ 'asc', 'desc' ],\n\n\n\t/**\n\t * Enable or disable filtering on the data in this column.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @name DataTable.defaults.column.searchable\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"searchable\": false, \"targets\": [ 0 ] }\n\t * ] } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"searchable\": false },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ] } );\n\t * } );\n\t */\n\t\"bSearchable\": true,\n\n\n\t/**\n\t * Enable or disable ordering on this column.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @name DataTable.defaults.column.orderable\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"orderable\": false, \"targets\": [ 0 ] }\n\t * ] } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"orderable\": false },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ] } );\n\t * } );\n\t */\n\t\"bSortable\": true,\n\n\n\t/**\n\t * Enable or disable the display of this column.\n\t * @type boolean\n\t * @default true\n\t *\n\t * @name DataTable.defaults.column.visible\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"visible\": false, \"targets\": [ 0 ] }\n\t * ] } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"visible\": false },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ] } );\n\t * } );\n\t */\n\t\"bVisible\": true,\n\n\n\t/**\n\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t * allowing you to modify the DOM element (add background colour for example) when the\n\t * element is available.\n\t * @type function\n\t * @param {element} td The TD node that has been created\n\t * @param {*} cellData The Data for the cell\n\t * @param {array|object} rowData The data for the whole row\n\t * @param {int} row The row index for the aoData data store\n\t * @param {int} col The column index for aoColumns\n\t *\n\t * @name DataTable.defaults.column.createdCell\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [3],\n\t * \"createdCell\": function (td, cellData, rowData, row, col) {\n\t * if ( cellData == \"1.7\" ) {\n\t * $(td).css('color', 'blue')\n\t * }\n\t * }\n\t * } ]\n\t * });\n\t * } );\n\t */\n\t\"fnCreatedCell\": null,\n\n\n\t/**\n\t * This parameter has been replaced by `data` in DataTables to ensure naming\n\t * consistency. `dataProp` can still be used, as there is backwards\n\t * compatibility in DataTables for this option, but it is strongly\n\t * recommended that you use `data` in preference to `dataProp`.\n\t * @name DataTable.defaults.column.dataProp\n\t */\n\n\n\t/**\n\t * This property can be used to read data from any data source property,\n\t * including deeply nested objects / properties. `data` can be given in a\n\t * number of different ways which effect its behaviour:\n\t *\n\t * * `integer` - treated as an array index for the data source. This is the\n\t * default that DataTables uses (incrementally increased for each column).\n\t * * `string` - read an object property from the data source. There are\n\t * three 'special' options that can be used in the string to alter how\n\t * DataTables reads the data from the source object:\n\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t * Javascript to read from nested objects, so to can the options\n\t * specified in `data`. For example: `browser.version` or\n\t * `browser.name`. If your object parameter name contains a period, use\n\t * `\\\\` to escape it - i.e. `first\\\\.name`.\n\t * * `[]` - Array notation. DataTables can automatically combine data\n\t * from and array source, joining the data with the characters provided\n\t * between the two brackets. For example: `name[, ]` would provide a\n\t * comma-space separated list from the source array. If no characters\n\t * are provided between the brackets, the original array source is\n\t * returned.\n\t * * `()` - Function notation. Adding `()` to the end of a parameter will\n\t * execute a function of the name given. For example: `browser()` for a\n\t * simple function on the data source, `browser.version()` for a\n\t * function in a nested property or even `browser().version` to get an\n\t * object property if the function called returns an object. Note that\n\t * function notation is recommended for use in `render` rather than\n\t * `data` as it is much simpler to use as a renderer.\n\t * * `null` - use the original data source for the row rather than plucking\n\t * data directly from it. This action has effects on two other\n\t * initialisation options:\n\t * * `defaultContent` - When null is given as the `data` option and\n\t * `defaultContent` is specified for the column, the value defined by\n\t * `defaultContent` will be used for the cell.\n\t * * `render` - When null is used for the `data` option and the `render`\n\t * option is specified for the column, the whole data source for the\n\t * row is used for the renderer.\n\t * * `function` - the function given will be executed whenever DataTables\n\t * needs to set or get the data for a cell in the column. The function\n\t * takes three parameters:\n\t * * Parameters:\n\t * * `{array|object}` The data source for the row\n\t * * `{string}` The type call data requested - this will be 'set' when\n\t * setting data or 'filter', 'display', 'type', 'sort' or undefined\n\t * when gathering data. Note that when `undefined` is given for the\n\t * type DataTables expects to get the raw data for the object back<\n\t * * `{*}` Data to set when the second parameter is 'set'.\n\t * * Return:\n\t * * The return value from the function is not required when 'set' is\n\t * the type of call, but otherwise the return is what will be used\n\t * for the data requested.\n\t *\n\t * Note that `data` is a getter and setter option. If you just require\n\t * formatting of data for output, you will likely want to use `render` which\n\t * is simply a getter and thus simpler to use.\n\t *\n\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\n\t * name change reflects the flexibility of this property and is consistent\n\t * with the naming of mRender. If 'mDataProp' is given, then it will still\n\t * be used by DataTables, as it automatically maps the old name to the new\n\t * if required.\n\t *\n\t * @type string|int|function|null\n\t * @default null Use automatically calculated column index\n\t *\n\t * @name DataTable.defaults.column.data\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Read table data from objects\n\t * // JSON structure for each row:\n\t * // {\n\t * // \"engine\": {value},\n\t * // \"browser\": {value},\n\t * // \"platform\": {value},\n\t * // \"version\": {value},\n\t * // \"grade\": {value}\n\t * // }\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"ajaxSource\": \"sources/objects.txt\",\n\t * \"columns\": [\n\t * { \"data\": \"engine\" },\n\t * { \"data\": \"browser\" },\n\t * { \"data\": \"platform\" },\n\t * { \"data\": \"version\" },\n\t * { \"data\": \"grade\" }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Read information from deeply nested objects\n\t * // JSON structure for each row:\n\t * // {\n\t * // \"engine\": {value},\n\t * // \"browser\": {value},\n\t * // \"platform\": {\n\t * // \"inner\": {value}\n\t * // },\n\t * // \"details\": [\n\t * // {value}, {value}\n\t * // ]\n\t * // }\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"ajaxSource\": \"sources/deep.txt\",\n\t * \"columns\": [\n\t * { \"data\": \"engine\" },\n\t * { \"data\": \"browser\" },\n\t * { \"data\": \"platform.inner\" },\n\t * { \"data\": \"details.0\" },\n\t * { \"data\": \"details.1\" }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `data` as a function to provide different information for\n\t * // sorting, filtering and display. In this case, currency (price)\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": function ( source, type, val ) {\n\t * if (type === 'set') {\n\t * source.price = val;\n\t * // Store the computed display and filter values for efficiency\n\t * source.price_display = val==\"\" ? \"\" : \"$\"+numberFormat(val);\n\t * source.price_filter = val==\"\" ? \"\" : \"$\"+numberFormat(val)+\" \"+val;\n\t * return;\n\t * }\n\t * else if (type === 'display') {\n\t * return source.price_display;\n\t * }\n\t * else if (type === 'filter') {\n\t * return source.price_filter;\n\t * }\n\t * // 'sort', 'type' and undefined all just use the integer\n\t * return source.price;\n\t * }\n\t * } ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using default content\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": null,\n\t * \"defaultContent\": \"Click to edit\"\n\t * } ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using array notation - outputting a list from an array\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": \"name[, ]\"\n\t * } ]\n\t * } );\n\t * } );\n\t *\n\t */\n\t\"mData\": null,\n\n\n\t/**\n\t * This property is the rendering partner to `data` and it is suggested that\n\t * when you want to manipulate data for display (including filtering,\n\t * sorting etc) without altering the underlying data for the table, use this\n\t * property. `render` can be considered to be the the read only companion to\n\t * `data` which is read / write (then as such more complex). Like `data`\n\t * this option can be given in a number of different ways to effect its\n\t * behaviour:\n\t *\n\t * * `integer` - treated as an array index for the data source. This is the\n\t * default that DataTables uses (incrementally increased for each column).\n\t * * `string` - read an object property from the data source. There are\n\t * three 'special' options that can be used in the string to alter how\n\t * DataTables reads the data from the source object:\n\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t * Javascript to read from nested objects, so to can the options\n\t * specified in `data`. For example: `browser.version` or\n\t * `browser.name`. If your object parameter name contains a period, use\n\t * `\\\\` to escape it - i.e. `first\\\\.name`.\n\t * * `[]` - Array notation. DataTables can automatically combine data\n\t * from and array source, joining the data with the characters provided\n\t * between the two brackets. For example: `name[, ]` would provide a\n\t * comma-space separated list from the source array. If no characters\n\t * are provided between the brackets, the original array source is\n\t * returned.\n\t * * `()` - Function notation. Adding `()` to the end of a parameter will\n\t * execute a function of the name given. For example: `browser()` for a\n\t * simple function on the data source, `browser.version()` for a\n\t * function in a nested property or even `browser().version` to get an\n\t * object property if the function called returns an object.\n\t * * `object` - use different data for the different data types requested by\n\t * DataTables ('filter', 'display', 'type' or 'sort'). The property names\n\t * of the object is the data type the property refers to and the value can\n\t * defined using an integer, string or function using the same rules as\n\t * `render` normally does. Note that an `_` option _must_ be specified.\n\t * This is the default value to use if you haven't specified a value for\n\t * the data type requested by DataTables.\n\t * * `function` - the function given will be executed whenever DataTables\n\t * needs to set or get the data for a cell in the column. The function\n\t * takes three parameters:\n\t * * Parameters:\n\t * * {array|object} The data source for the row (based on `data`)\n\t * * {string} The type call data requested - this will be 'filter',\n\t * 'display', 'type' or 'sort'.\n\t * * {array|object} The full data source for the row (not based on\n\t * `data`)\n\t * * Return:\n\t * * The return value from the function is what will be used for the\n\t * data requested.\n\t *\n\t * @type string|int|function|object|null\n\t * @default null Use the data source value.\n\t *\n\t * @name DataTable.defaults.column.render\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Create a comma separated list from an array of objects\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"ajaxSource\": \"sources/deep.txt\",\n\t * \"columns\": [\n\t * { \"data\": \"engine\" },\n\t * { \"data\": \"browser\" },\n\t * {\n\t * \"data\": \"platform\",\n\t * \"render\": \"[, ].name\"\n\t * }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Execute a function to obtain data\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": null, // Use the full data source object for the renderer's source\n\t * \"render\": \"browserName()\"\n\t * } ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // As an object, extracting different data for the different types\n\t * // This would be used with a data source such as:\n\t * // { \"phone\": 5552368, \"phone_filter\": \"5552368 555-2368\", \"phone_display\": \"555-2368\" }\n\t * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\n\t * // (which has both forms) is used for filtering for if a user inputs either format, while\n\t * // the formatted phone number is the one that is shown in the table.\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": null, // Use the full data source object for the renderer's source\n\t * \"render\": {\n\t * \"_\": \"phone\",\n\t * \"filter\": \"phone_filter\",\n\t * \"display\": \"phone_display\"\n\t * }\n\t * } ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Use as a function to create a link from the data source\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"data\": \"download_link\",\n\t * \"render\": function ( data, type, full ) {\n\t * return 'Download';\n\t * }\n\t * } ]\n\t * } );\n\t * } );\n\t */\n\t\"mRender\": null,\n\n\n\t/**\n\t * Change the cell type created for the column - either TD cells or TH cells. This\n\t * can be useful as TH cells have semantic meaning in the table body, allowing them\n\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\n\t * @type string\n\t * @default td\n\t *\n\t * @name DataTable.defaults.column.cellType\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Make the first column use TH cells\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [ {\n\t * \"targets\": [ 0 ],\n\t * \"cellType\": \"th\"\n\t * } ]\n\t * } );\n\t * } );\n\t */\n\t\"sCellType\": \"td\",\n\n\n\t/**\n\t * Class to give to each cell in this column.\n\t * @type string\n\t * @default Empty string\n\t *\n\t * @name DataTable.defaults.column.class\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"class\": \"my_class\", \"targets\": [ 0 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"class\": \"my_class\" },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sClass\": \"\",\n\n\t/**\n\t * When DataTables calculates the column widths to assign to each column,\n\t * it finds the longest string in each column and then constructs a\n\t * temporary table and reads the widths from that. The problem with this\n\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t * string - thus the calculation can go wrong (doing it properly and putting\n\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t * a \"work around\" we provide this option. It will append its value to the\n\t * text that is found to be the longest string for the column - i.e. padding.\n\t * Generally you shouldn't need this!\n\t * @type string\n\t * @default Empty string\n\t *\n\t * @name DataTable.defaults.column.contentPadding\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * null,\n\t * null,\n\t * null,\n\t * {\n\t * \"contentPadding\": \"mmm\"\n\t * }\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sContentPadding\": \"\",\n\n\n\t/**\n\t * Allows a default value to be given for a column's data, and will be used\n\t * whenever a null data source is encountered (this can be because `data`\n\t * is set to null, or because the data source itself is null).\n\t * @type string\n\t * @default null\n\t *\n\t * @name DataTable.defaults.column.defaultContent\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * {\n\t * \"data\": null,\n\t * \"defaultContent\": \"Edit\",\n\t * \"targets\": [ -1 ]\n\t * }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * null,\n\t * null,\n\t * null,\n\t * {\n\t * \"data\": null,\n\t * \"defaultContent\": \"Edit\"\n\t * }\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sDefaultContent\": null,\n\n\n\t/**\n\t * This parameter is only used in DataTables' server-side processing. It can\n\t * be exceptionally useful to know what columns are being displayed on the\n\t * client side, and to map these to database fields. When defined, the names\n\t * also allow DataTables to reorder information from the server if it comes\n\t * back in an unexpected order (i.e. if you switch your columns around on the\n\t * client-side, your server-side code does not also need updating).\n\t * @type string\n\t * @default Empty string\n\t *\n\t * @name DataTable.defaults.column.name\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"name\": \"engine\", \"targets\": [ 0 ] },\n\t * { \"name\": \"browser\", \"targets\": [ 1 ] },\n\t * { \"name\": \"platform\", \"targets\": [ 2 ] },\n\t * { \"name\": \"version\", \"targets\": [ 3 ] },\n\t * { \"name\": \"grade\", \"targets\": [ 4 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"name\": \"engine\" },\n\t * { \"name\": \"browser\" },\n\t * { \"name\": \"platform\" },\n\t * { \"name\": \"version\" },\n\t * { \"name\": \"grade\" }\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sName\": \"\",\n\n\n\t/**\n\t * Defines a data source type for the ordering which can be used to read\n\t * real-time information from the table (updating the internally cached\n\t * version) prior to ordering. This allows ordering to occur on user\n\t * editable elements such as form inputs.\n\t * @type string\n\t * @default std\n\t *\n\t * @name DataTable.defaults.column.orderDataType\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"orderDataType\": \"dom-text\", \"targets\": [ 2, 3 ] },\n\t * { \"type\": \"numeric\", \"targets\": [ 3 ] },\n\t * { \"orderDataType\": \"dom-select\", \"targets\": [ 4 ] },\n\t * { \"orderDataType\": \"dom-checkbox\", \"targets\": [ 5 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * null,\n\t * null,\n\t * { \"orderDataType\": \"dom-text\" },\n\t * { \"orderDataType\": \"dom-text\", \"type\": \"numeric\" },\n\t * { \"orderDataType\": \"dom-select\" },\n\t * { \"orderDataType\": \"dom-checkbox\" }\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sSortDataType\": \"std\",\n\n\n\t/**\n\t * The title of this column.\n\t * @type string\n\t * @default null Derived from the 'TH' value for this column in the\n\t * original HTML table.\n\t *\n\t * @name DataTable.defaults.column.title\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"title\": \"My column title\", \"targets\": [ 0 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"title\": \"My column title\" },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sTitle\": null,\n\n\n\t/**\n\t * The type allows you to specify how the data for this column will be\n\t * ordered. Four types (string, numeric, date and html (which will strip\n\t * HTML tags before ordering)) are currently available. Note that only date\n\t * formats understood by Javascript's Date() object will be accepted as type\n\t * date. For example: \"Mar 26, 2008 5:03 PM\". May take the values: 'string',\n\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\n\t * through plug-ins.\n\t * @type string\n\t * @default null Auto-detected from raw data\n\t *\n\t * @name DataTable.defaults.column.type\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"type\": \"html\", \"targets\": [ 0 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"type\": \"html\" },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sType\": null,\n\n\n\t/**\n\t * Defining the width of the column, this parameter may take any CSS value\n\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\n\t * been given a specific width through this interface ensuring that the table\n\t * remains readable.\n\t * @type string\n\t * @default null Automatic\n\t *\n\t * @name DataTable.defaults.column.width\n\t * @dtopt Columns\n\t *\n\t * @example\n\t * // Using `columnDefs`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columnDefs\": [\n\t * { \"width\": \"20%\", \"targets\": [ 0 ] }\n\t * ]\n\t * } );\n\t * } );\n\t *\n\t * @example\n\t * // Using `columns`\n\t * $(document).ready( function() {\n\t * $('#example').dataTable( {\n\t * \"columns\": [\n\t * { \"width\": \"20%\" },\n\t * null,\n\t * null,\n\t * null,\n\t * null\n\t * ]\n\t * } );\n\t * } );\n\t */\n\t\"sWidth\": null\n};\n\n_fnHungarianMap( DataTable.defaults.column );\n\n\n\n/**\n * DataTables settings object - this holds all the information needed for a\n * given table, including configuration, data and current application of the\n * table options. DataTables does not have a single instance for each DataTable\n * with the settings attached to that instance, but rather instances of the\n * DataTable \"class\" are created on-the-fly as needed (typically by a\n * $().dataTable() call) and the settings object is then applied to that\n * instance.\n *\n * Note that this object is related to {@link DataTable.defaults} but this\n * one is the internal data store for DataTables's cache of columns. It should\n * NOT be manipulated outside of DataTables. Any configuration should be done\n * through the initialisation options.\n * @namespace\n * @todo Really should attach the settings object to individual instances so we\n * don't need to create new instances on each $().dataTable() call (if the\n * table already exists). It would also save passing oSettings around and\n * into every single function. However, this is a very significant\n * architecture change for DataTables and will almost certainly break\n * backwards compatibility with older installations. This is something that\n * will be done in 2.0.\n */\nDataTable.models.oSettings = {\n\t/**\n\t * Primary features of DataTables and their enablement state.\n\t * @namespace\n\t */\n\t\"oFeatures\": {\n\n\t\t/**\n\t\t * Flag to say if DataTables should automatically try to calculate the\n\t\t * optimum table and columns widths (true) or not (false).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bAutoWidth\": null,\n\n\t\t/**\n\t\t * Delay the creation of TR and TD elements until they are actually\n\t\t * needed by a driven page draw. This can give a significant speed\n\t\t * increase for Ajax source and Javascript source data, but makes no\n\t\t * difference at all for DOM and server-side processing tables.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bDeferRender\": null,\n\n\t\t/**\n\t\t * Enable filtering on the table or not. Note that if this is disabled\n\t\t * then there is no filtering at all on the table, including fnFilter.\n\t\t * To just remove the filtering input use sDom and remove the 'f' option.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bFilter\": null,\n\n\t\t/**\n\t\t * Table information element (the 'Showing x of y records' div) enable\n\t\t * flag.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bInfo\": null,\n\n\t\t/**\n\t\t * Present a user control allowing the end user to change the page size\n\t\t * when pagination is enabled.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bLengthChange\": null,\n\n\t\t/**\n\t\t * Pagination enabled or not. Note that if this is disabled then length\n\t\t * changing must also be disabled.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bPaginate\": null,\n\n\t\t/**\n\t\t * Processing indicator enable flag whenever DataTables is enacting a\n\t\t * user request - typically an Ajax request for server-side processing.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bProcessing\": null,\n\n\t\t/**\n\t\t * Server-side processing enabled flag - when enabled DataTables will\n\t\t * get all data from the server for every draw - there is no filtering,\n\t\t * sorting or paging done on the client-side.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bServerSide\": null,\n\n\t\t/**\n\t\t * Sorting enablement flag.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bSort\": null,\n\n\t\t/**\n\t\t * Multi-column sorting\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bSortMulti\": null,\n\n\t\t/**\n\t\t * Apply a class to the columns which are being sorted to provide a\n\t\t * visual highlight or not. This can slow things down when enabled since\n\t\t * there is a lot of DOM interaction.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bSortClasses\": null,\n\n\t\t/**\n\t\t * State saving enablement flag.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bStateSave\": null\n\t},\n\n\n\t/**\n\t * Scrolling settings for a table.\n\t * @namespace\n\t */\n\t\"oScroll\": {\n\t\t/**\n\t\t * When the table is shorter in height than sScrollY, collapse the\n\t\t * table container down to the height of the table (when true).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type boolean\n\t\t */\n\t\t\"bCollapse\": null,\n\n\t\t/**\n\t\t * Width of the scrollbar for the web-browser's platform. Calculated\n\t\t * during table initialisation.\n\t\t * @type int\n\t\t * @default 0\n\t\t */\n\t\t\"iBarWidth\": 0,\n\n\t\t/**\n\t\t * Viewport width for horizontal scrolling. Horizontal scrolling is\n\t\t * disabled if an empty string.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type string\n\t\t */\n\t\t\"sX\": null,\n\n\t\t/**\n\t\t * Width to expand the table to when using x-scrolling. Typically you\n\t\t * should not need to use this.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type string\n\t\t * @deprecated\n\t\t */\n\t\t\"sXInner\": null,\n\n\t\t/**\n\t\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\n\t\t * if an empty string.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t * @type string\n\t\t */\n\t\t\"sY\": null\n\t},\n\n\t/**\n\t * Language information for the table.\n\t * @namespace\n\t * @extends DataTable.defaults.oLanguage\n\t */\n\t\"oLanguage\": {\n\t\t/**\n\t\t * Information callback function. See\n\t\t * {@link DataTable.defaults.fnInfoCallback}\n\t\t * @type function\n\t\t * @default null\n\t\t */\n\t\t\"fnInfoCallback\": null\n\t},\n\n\t/**\n\t * Browser support parameters\n\t * @namespace\n\t */\n\t\"oBrowser\": {\n\t\t/**\n\t\t * Indicate if the browser incorrectly calculates width:100% inside a\n\t\t * scrolling element (IE6/7)\n\t\t * @type boolean\n\t\t * @default false\n\t\t */\n\t\t\"bScrollOversize\": false,\n\n\t\t/**\n\t\t * Determine if the vertical scrollbar is on the right or left of the\n\t\t * scrolling container - needed for rtl language layout, although not\n\t\t * all browsers move the scrollbar (Safari).\n\t\t * @type boolean\n\t\t * @default false\n\t\t */\n\t\t\"bScrollbarLeft\": false,\n\n\t\t/**\n\t\t * Flag for if `getBoundingClientRect` is fully supported or not\n\t\t * @type boolean\n\t\t * @default false\n\t\t */\n\t\t\"bBounding\": false,\n\n\t\t/**\n\t\t * Browser scrollbar width\n\t\t * @type integer\n\t\t * @default 0\n\t\t */\n\t\t\"barWidth\": 0\n\t},\n\n\n\t\"ajax\": null,\n\n\n\t/**\n\t * Array referencing the nodes which are used for the features. The\n\t * parameters of this object match what is allowed by sDom - i.e.\n\t *
\n\t *
'l' - Length changing
\n\t *
'f' - Filtering input
\n\t *
't' - The table!
\n\t *
'i' - Information
\n\t *
'p' - Pagination
\n\t *
'r' - pRocessing
\n\t *
\n\t * @type array\n\t * @default []\n\t */\n\t\"aanFeatures\": [],\n\n\t/**\n\t * Store data information - see {@link DataTable.models.oRow} for detailed\n\t * information.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoData\": [],\n\n\t/**\n\t * Array of indexes which are in the current display (after filtering etc)\n\t * @type array\n\t * @default []\n\t */\n\t\"aiDisplay\": [],\n\n\t/**\n\t * Array of indexes for display - no filtering\n\t * @type array\n\t * @default []\n\t */\n\t\"aiDisplayMaster\": [],\n\n\t/**\n\t * Map of row ids to data indexes\n\t * @type object\n\t * @default {}\n\t */\n\t\"aIds\": {},\n\n\t/**\n\t * Store information about each column that is in use\n\t * @type array\n\t * @default []\n\t */\n\t\"aoColumns\": [],\n\n\t/**\n\t * Store information about the table's header\n\t * @type array\n\t * @default []\n\t */\n\t\"aoHeader\": [],\n\n\t/**\n\t * Store information about the table's footer\n\t * @type array\n\t * @default []\n\t */\n\t\"aoFooter\": [],\n\n\t/**\n\t * Store the applied global search information in case we want to force a\n\t * research or compare the old search to a new one.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @namespace\n\t * @extends DataTable.models.oSearch\n\t */\n\t\"oPreviousSearch\": {},\n\n\t/**\n\t * Store the applied search for each column - see\n\t * {@link DataTable.models.oSearch} for the format that is used for the\n\t * filtering information for each column.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoPreSearchCols\": [],\n\n\t/**\n\t * Sorting that is applied to the table. Note that the inner arrays are\n\t * used in the following manner:\n\t *
\n\t *
Index 0 - column number
\n\t *
Index 1 - current sorting direction
\n\t *
\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type array\n\t * @todo These inner arrays should really be objects\n\t */\n\t\"aaSorting\": null,\n\n\t/**\n\t * Sorting that is always applied to the table (i.e. prefixed in front of\n\t * aaSorting).\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type array\n\t * @default []\n\t */\n\t\"aaSortingFixed\": [],\n\n\t/**\n\t * Classes to use for the striping of a table.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type array\n\t * @default []\n\t */\n\t\"asStripeClasses\": null,\n\n\t/**\n\t * If restoring a table - we should restore its striping classes as well\n\t * @type array\n\t * @default []\n\t */\n\t\"asDestroyStripes\": [],\n\n\t/**\n\t * If restoring a table - we should restore its width\n\t * @type int\n\t * @default 0\n\t */\n\t\"sDestroyWidth\": 0,\n\n\t/**\n\t * Callback functions array for every time a row is inserted (i.e. on a draw).\n\t * @type array\n\t * @default []\n\t */\n\t\"aoRowCallback\": [],\n\n\t/**\n\t * Callback functions for the header on each draw.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoHeaderCallback\": [],\n\n\t/**\n\t * Callback function for the footer on each draw.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoFooterCallback\": [],\n\n\t/**\n\t * Array of callback functions for draw callback functions\n\t * @type array\n\t * @default []\n\t */\n\t\"aoDrawCallback\": [],\n\n\t/**\n\t * Array of callback functions for row created function\n\t * @type array\n\t * @default []\n\t */\n\t\"aoRowCreatedCallback\": [],\n\n\t/**\n\t * Callback functions for just before the table is redrawn. A return of\n\t * false will be used to cancel the draw.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoPreDrawCallback\": [],\n\n\t/**\n\t * Callback functions for when the table has been initialised.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoInitComplete\": [],\n\n\n\t/**\n\t * Callbacks for modifying the settings to be stored for state saving, prior to\n\t * saving state.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoStateSaveParams\": [],\n\n\t/**\n\t * Callbacks for modifying the settings that have been stored for state saving\n\t * prior to using the stored values to restore the state.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoStateLoadParams\": [],\n\n\t/**\n\t * Callbacks for operating on the settings object once the saved state has been\n\t * loaded\n\t * @type array\n\t * @default []\n\t */\n\t\"aoStateLoaded\": [],\n\n\t/**\n\t * Cache the table ID for quick access\n\t * @type string\n\t * @default Empty string\n\t */\n\t\"sTableId\": \"\",\n\n\t/**\n\t * The TABLE node for the main table\n\t * @type node\n\t * @default null\n\t */\n\t\"nTable\": null,\n\n\t/**\n\t * Permanent ref to the thead element\n\t * @type node\n\t * @default null\n\t */\n\t\"nTHead\": null,\n\n\t/**\n\t * Permanent ref to the tfoot element - if it exists\n\t * @type node\n\t * @default null\n\t */\n\t\"nTFoot\": null,\n\n\t/**\n\t * Permanent ref to the tbody element\n\t * @type node\n\t * @default null\n\t */\n\t\"nTBody\": null,\n\n\t/**\n\t * Cache the wrapper node (contains all DataTables controlled elements)\n\t * @type node\n\t * @default null\n\t */\n\t\"nTableWrapper\": null,\n\n\t/**\n\t * Indicate if when using server-side processing the loading of data\n\t * should be deferred until the second draw.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type boolean\n\t * @default false\n\t */\n\t\"bDeferLoading\": false,\n\n\t/**\n\t * Indicate if all required information has been read in\n\t * @type boolean\n\t * @default false\n\t */\n\t\"bInitialised\": false,\n\n\t/**\n\t * Information about open rows. Each object in the array has the parameters\n\t * 'nTr' and 'nParent'\n\t * @type array\n\t * @default []\n\t */\n\t\"aoOpenRows\": [],\n\n\t/**\n\t * Dictate the positioning of DataTables' control elements - see\n\t * {@link DataTable.model.oInit.sDom}.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type string\n\t * @default null\n\t */\n\t\"sDom\": null,\n\n\t/**\n\t * Search delay (in mS)\n\t * @type integer\n\t * @default null\n\t */\n\t\"searchDelay\": null,\n\n\t/**\n\t * Which type of pagination should be used.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type string\n\t * @default two_button\n\t */\n\t\"sPaginationType\": \"two_button\",\n\n\t/**\n\t * The state duration (for `stateSave`) in seconds.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type int\n\t * @default 0\n\t */\n\t\"iStateDuration\": 0,\n\n\t/**\n\t * Array of callback functions for state saving. Each array element is an\n\t * object with the following parameters:\n\t *
\n\t *
function:fn - function to call. Takes two parameters, oSettings\n\t * and the JSON string to save that has been thus far created. Returns\n\t * a JSON string to be inserted into a json object\n\t * (i.e. '\"param\": [ 0, 1, 2]')
\n\t *
string:sName - name of callback
\n\t *
\n\t * @type array\n\t * @default []\n\t */\n\t\"aoStateSave\": [],\n\n\t/**\n\t * Array of callback functions for state loading. Each array element is an\n\t * object with the following parameters:\n\t *
\n\t *
function:fn - function to call. Takes two parameters, oSettings\n\t * and the object stored. May return false to cancel state loading
\n\t *
string:sName - name of callback
\n\t *
\n\t * @type array\n\t * @default []\n\t */\n\t\"aoStateLoad\": [],\n\n\t/**\n\t * State that was saved. Useful for back reference\n\t * @type object\n\t * @default null\n\t */\n\t\"oSavedState\": null,\n\n\t/**\n\t * State that was loaded. Useful for back reference\n\t * @type object\n\t * @default null\n\t */\n\t\"oLoadedState\": null,\n\n\t/**\n\t * Source url for AJAX data for the table.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type string\n\t * @default null\n\t */\n\t\"sAjaxSource\": null,\n\n\t/**\n\t * Property from a given object from which to read the table data from. This\n\t * can be an empty string (when not server-side processing), in which case\n\t * it is assumed an an array is given directly.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type string\n\t */\n\t\"sAjaxDataProp\": null,\n\n\t/**\n\t * The last jQuery XHR object that was used for server-side data gathering.\n\t * This can be used for working with the XHR information in one of the\n\t * callbacks\n\t * @type object\n\t * @default null\n\t */\n\t\"jqXHR\": null,\n\n\t/**\n\t * JSON returned from the server in the last Ajax request\n\t * @type object\n\t * @default undefined\n\t */\n\t\"json\": undefined,\n\n\t/**\n\t * Data submitted as part of the last Ajax request\n\t * @type object\n\t * @default undefined\n\t */\n\t\"oAjaxData\": undefined,\n\n\t/**\n\t * Function to get the server-side data.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type function\n\t */\n\t\"fnServerData\": null,\n\n\t/**\n\t * Functions which are called prior to sending an Ajax request so extra\n\t * parameters can easily be sent to the server\n\t * @type array\n\t * @default []\n\t */\n\t\"aoServerParams\": [],\n\n\t/**\n\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\n\t * required).\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type string\n\t */\n\t\"sServerMethod\": null,\n\n\t/**\n\t * Format numbers for display.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type function\n\t */\n\t\"fnFormatNumber\": null,\n\n\t/**\n\t * List of options that can be used for the user selectable length menu.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type array\n\t * @default []\n\t */\n\t\"aLengthMenu\": null,\n\n\t/**\n\t * Counter for the draws that the table does. Also used as a tracker for\n\t * server-side processing\n\t * @type int\n\t * @default 0\n\t */\n\t\"iDraw\": 0,\n\n\t/**\n\t * Indicate if a redraw is being done - useful for Ajax\n\t * @type boolean\n\t * @default false\n\t */\n\t\"bDrawing\": false,\n\n\t/**\n\t * Draw index (iDraw) of the last error when parsing the returned data\n\t * @type int\n\t * @default -1\n\t */\n\t\"iDrawError\": -1,\n\n\t/**\n\t * Paging display length\n\t * @type int\n\t * @default 10\n\t */\n\t\"_iDisplayLength\": 10,\n\n\t/**\n\t * Paging start point - aiDisplay index\n\t * @type int\n\t * @default 0\n\t */\n\t\"_iDisplayStart\": 0,\n\n\t/**\n\t * Server-side processing - number of records in the result set\n\t * (i.e. before filtering), Use fnRecordsTotal rather than\n\t * this property to get the value of the number of records, regardless of\n\t * the server-side processing setting.\n\t * @type int\n\t * @default 0\n\t * @private\n\t */\n\t\"_iRecordsTotal\": 0,\n\n\t/**\n\t * Server-side processing - number of records in the current display set\n\t * (i.e. after filtering). Use fnRecordsDisplay rather than\n\t * this property to get the value of the number of records, regardless of\n\t * the server-side processing setting.\n\t * @type boolean\n\t * @default 0\n\t * @private\n\t */\n\t\"_iRecordsDisplay\": 0,\n\n\t/**\n\t * The classes to use for the table\n\t * @type object\n\t * @default {}\n\t */\n\t\"oClasses\": {},\n\n\t/**\n\t * Flag attached to the settings object so you can check in the draw\n\t * callback if filtering has been done in the draw. Deprecated in favour of\n\t * events.\n\t * @type boolean\n\t * @default false\n\t * @deprecated\n\t */\n\t\"bFiltered\": false,\n\n\t/**\n\t * Flag attached to the settings object so you can check in the draw\n\t * callback if sorting has been done in the draw. Deprecated in favour of\n\t * events.\n\t * @type boolean\n\t * @default false\n\t * @deprecated\n\t */\n\t\"bSorted\": false,\n\n\t/**\n\t * Indicate that if multiple rows are in the header and there is more than\n\t * one unique cell per column, if the top one (true) or bottom one (false)\n\t * should be used for sorting / title by DataTables.\n\t * Note that this parameter will be set by the initialisation routine. To\n\t * set a default use {@link DataTable.defaults}.\n\t * @type boolean\n\t */\n\t\"bSortCellsTop\": null,\n\n\t/**\n\t * Initialisation object that is used for the table\n\t * @type object\n\t * @default null\n\t */\n\t\"oInit\": null,\n\n\t/**\n\t * Destroy callback functions - for plug-ins to attach themselves to the\n\t * destroy so they can clean up markup and events.\n\t * @type array\n\t * @default []\n\t */\n\t\"aoDestroyCallback\": [],\n\n\n\t/**\n\t * Get the number of records in the current record set, before filtering\n\t * @type function\n\t */\n\t\"fnRecordsTotal\": function ()\n\t{\n\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\tthis._iRecordsTotal * 1 :\n\t\t\tthis.aiDisplayMaster.length;\n\t},\n\n\t/**\n\t * Get the number of records in the current record set, after filtering\n\t * @type function\n\t */\n\t\"fnRecordsDisplay\": function ()\n\t{\n\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\tthis._iRecordsDisplay * 1 :\n\t\t\tthis.aiDisplay.length;\n\t},\n\n\t/**\n\t * Get the display end point - aiDisplay index\n\t * @type function\n\t */\n\t\"fnDisplayEnd\": function ()\n\t{\n\t\tvar\n\t\t\tlen = this._iDisplayLength,\n\t\t\tstart = this._iDisplayStart,\n\t\t\tcalc = start + len,\n\t\t\trecords = this.aiDisplay.length,\n\t\t\tfeatures = this.oFeatures,\n\t\t\tpaginate = features.bPaginate;\n\n\t\tif ( features.bServerSide ) {\n\t\t\treturn paginate === false || len === -1 ?\n\t\t\t\tstart + records :\n\t\t\t\tMath.min( start+len, this._iRecordsDisplay );\n\t\t}\n\t\telse {\n\t\t\treturn ! paginate || calc>records || len===-1 ?\n\t\t\t\trecords :\n\t\t\t\tcalc;\n\t\t}\n\t},\n\n\t/**\n\t * The DataTables object for this table\n\t * @type object\n\t * @default null\n\t */\n\t\"oInstance\": null,\n\n\t/**\n\t * Unique identifier for each instance of the DataTables object. If there\n\t * is an ID on the table node, then it takes that value, otherwise an\n\t * incrementing internal counter is used.\n\t * @type string\n\t * @default null\n\t */\n\t\"sInstance\": null,\n\n\t/**\n\t * tabindex attribute value that is added to DataTables control elements, allowing\n\t * keyboard navigation of the table and its controls.\n\t */\n\t\"iTabIndex\": 0,\n\n\t/**\n\t * DIV container for the footer scrolling table if scrolling\n\t */\n\t\"nScrollHead\": null,\n\n\t/**\n\t * DIV container for the footer scrolling table if scrolling\n\t */\n\t\"nScrollFoot\": null,\n\n\t/**\n\t * Last applied sort\n\t * @type array\n\t * @default []\n\t */\n\t\"aLastSort\": [],\n\n\t/**\n\t * Stored plug-in instances\n\t * @type object\n\t * @default {}\n\t */\n\t\"oPlugins\": {},\n\n\t/**\n\t * Function used to get a row's id from the row's data\n\t * @type function\n\t * @default null\n\t */\n\t\"rowIdFn\": null,\n\n\t/**\n\t * Data location where to store a row's id\n\t * @type string\n\t * @default null\n\t */\n\t\"rowId\": null\n};\n\n/**\n * Extension object for DataTables that is used to provide all extension\n * options.\n *\n * Note that the `DataTable.ext` object is available through\n * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\n * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\n * @namespace\n * @extends DataTable.models.ext\n */\n\n\n/**\n * DataTables extensions\n * \n * This namespace acts as a collection area for plug-ins that can be used to\n * extend DataTables capabilities. Indeed many of the build in methods\n * use this method to provide their own capabilities (sorting methods for\n * example).\n *\n * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\n * reasons\n *\n * @namespace\n */\nDataTable.ext = _ext = {\n\t/**\n\t * Buttons. For use with the Buttons extension for DataTables. This is\n\t * defined here so other extensions can define buttons regardless of load\n\t * order. It is _not_ used by DataTables core.\n\t *\n\t * @type object\n\t * @default {}\n\t */\n\tbuttons: {},\n\n\n\t/**\n\t * Element class names\n\t *\n\t * @type object\n\t * @default {}\n\t */\n\tclasses: {},\n\n\n\t/**\n\t * DataTables build type (expanded by the download builder)\n\t *\n\t * @type string\n\t */\n\tbuilder: \"-source-\",\n\n\n\t/**\n\t * Error reporting.\n\t * \n\t * How should DataTables report an error. Can take the value 'alert',\n\t * 'throw', 'none' or a function.\n\t *\n\t * @type string|function\n\t * @default alert\n\t */\n\terrMode: \"alert\",\n\n\n\t/**\n\t * Feature plug-ins.\n\t * \n\t * This is an array of objects which describe the feature plug-ins that are\n\t * available to DataTables. These feature plug-ins are then available for\n\t * use through the `dom` initialisation option.\n\t * \n\t * Each feature plug-in is described by an object which must have the\n\t * following properties:\n\t * \n\t * * `fnInit` - function that is used to initialise the plug-in,\n\t * * `cFeature` - a character so the feature can be enabled by the `dom`\n\t * instillation option. This is case sensitive.\n\t *\n\t * The `fnInit` function has the following input parameters:\n\t *\n\t * 1. `{object}` DataTables settings object: see\n\t * {@link DataTable.models.oSettings}\n\t *\n\t * And the following return is expected:\n\t * \n\t * * {node|null} The element which contains your feature. Note that the\n\t * return may also be void if your plug-in does not require to inject any\n\t * DOM elements into DataTables control (`dom`) - for example this might\n\t * be useful when developing a plug-in which allows table control via\n\t * keyboard entry\n\t *\n\t * @type array\n\t *\n\t * @example\n\t * $.fn.dataTable.ext.features.push( {\n\t * \"fnInit\": function( oSettings ) {\n\t * return new TableTools( { \"oDTSettings\": oSettings } );\n\t * },\n\t * \"cFeature\": \"T\"\n\t * } );\n\t */\n\tfeature: [],\n\n\n\t/**\n\t * Row searching.\n\t * \n\t * This method of searching is complimentary to the default type based\n\t * searching, and a lot more comprehensive as it allows you complete control\n\t * over the searching logic. Each element in this array is a function\n\t * (parameters described below) that is called for every row in the table,\n\t * and your logic decides if it should be included in the searching data set\n\t * or not.\n\t *\n\t * Searching functions have the following input parameters:\n\t *\n\t * 1. `{object}` DataTables settings object: see\n\t * {@link DataTable.models.oSettings}\n\t * 2. `{array|object}` Data for the row to be processed (same as the\n\t * original format that was passed in as the data source, or an array\n\t * from a DOM data source\n\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\n\t * can be useful to retrieve the `TR` element if you need DOM interaction.\n\t *\n\t * And the following return is expected:\n\t *\n\t * * {boolean} Include the row in the searched result set (true) or not\n\t * (false)\n\t *\n\t * Note that as with the main search ability in DataTables, technically this\n\t * is \"filtering\", since it is subtractive. However, for consistency in\n\t * naming we call it searching here.\n\t *\n\t * @type array\n\t * @default []\n\t *\n\t * @example\n\t * // The following example shows custom search being applied to the\n\t * // fourth column (i.e. the data[3] index) based on two input values\n\t * // from the end-user, matching the data in a certain range.\n\t * $.fn.dataTable.ext.search.push(\n\t * function( settings, data, dataIndex ) {\n\t * var min = document.getElementById('min').value * 1;\n\t * var max = document.getElementById('max').value * 1;\n\t * var version = data[3] == \"-\" ? 0 : data[3]*1;\n\t *\n\t * if ( min == \"\" && max == \"\" ) {\n\t * return true;\n\t * }\n\t * else if ( min == \"\" && version < max ) {\n\t * return true;\n\t * }\n\t * else if ( min < version && \"\" == max ) {\n\t * return true;\n\t * }\n\t * else if ( min < version && version < max ) {\n\t * return true;\n\t * }\n\t * return false;\n\t * }\n\t * );\n\t */\n\tsearch: [],\n\n\n\t/**\n\t * Selector extensions\n\t *\n\t * The `selector` option can be used to extend the options available for the\n\t * selector modifier options (`selector-modifier` object data type) that\n\t * each of the three built in selector types offer (row, column and cell +\n\t * their plural counterparts). For example the Select extension uses this\n\t * mechanism to provide an option to select only rows, columns and cells\n\t * that have been marked as selected by the end user (`{selected: true}`),\n\t * which can be used in conjunction with the existing built in selector\n\t * options.\n\t *\n\t * Each property is an array to which functions can be pushed. The functions\n\t * take three attributes:\n\t *\n\t * * Settings object for the host table\n\t * * Options object (`selector-modifier` object type)\n\t * * Array of selected item indexes\n\t *\n\t * The return is an array of the resulting item indexes after the custom\n\t * selector has been applied.\n\t *\n\t * @type object\n\t */\n\tselector: {\n\t\tcell: [],\n\t\tcolumn: [],\n\t\trow: []\n\t},\n\n\n\t/**\n\t * Internal functions, exposed for used in plug-ins.\n\t * \n\t * Please note that you should not need to use the internal methods for\n\t * anything other than a plug-in (and even then, try to avoid if possible).\n\t * The internal function may change between releases.\n\t *\n\t * @type object\n\t * @default {}\n\t */\n\tinternal: {},\n\n\n\t/**\n\t * Legacy configuration options. Enable and disable legacy options that\n\t * are available in DataTables.\n\t *\n\t * @type object\n\t */\n\tlegacy: {\n\t\t/**\n\t\t * Enable / disable DataTables 1.9 compatible server-side processing\n\t\t * requests\n\t\t *\n\t\t * @type boolean\n\t\t * @default null\n\t\t */\n\t\tajax: null\n\t},\n\n\n\t/**\n\t * Pagination plug-in methods.\n\t * \n\t * Each entry in this object is a function and defines which buttons should\n\t * be shown by the pagination rendering method that is used for the table:\n\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\n\t * buttons are displayed in the document, while the functions here tell it\n\t * what buttons to display. This is done by returning an array of button\n\t * descriptions (what each button will do).\n\t *\n\t * Pagination types (the four built in options and any additional plug-in\n\t * options defined here) can be used through the `paginationType`\n\t * initialisation parameter.\n\t *\n\t * The functions defined take two parameters:\n\t *\n\t * 1. `{int} page` The current page index\n\t * 2. `{int} pages` The number of pages in the table\n\t *\n\t * Each function is expected to return an array where each element of the\n\t * array can be one of:\n\t *\n\t * * `first` - Jump to first page when activated\n\t * * `last` - Jump to last page when activated\n\t * * `previous` - Show previous page when activated\n\t * * `next` - Show next page when activated\n\t * * `{int}` - Show page of the index given\n\t * * `{array}` - A nested array containing the above elements to add a\n\t * containing 'DIV' element (might be useful for styling).\n\t *\n\t * Note that DataTables v1.9- used this object slightly differently whereby\n\t * an object with two functions would be defined for each plug-in. That\n\t * ability is still supported by DataTables 1.10+ to provide backwards\n\t * compatibility, but this option of use is now decremented and no longer\n\t * documented in DataTables 1.10+.\n\t *\n\t * @type object\n\t * @default {}\n\t *\n\t * @example\n\t * // Show previous, next and current page buttons only\n\t * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\n\t * return [ 'previous', page, 'next' ];\n\t * };\n\t */\n\tpager: {},\n\n\n\trenderer: {\n\t\tpageButton: {},\n\t\theader: {}\n\t},\n\n\n\t/**\n\t * Ordering plug-ins - custom data source\n\t * \n\t * The extension options for ordering of data available here is complimentary\n\t * to the default type based ordering that DataTables typically uses. It\n\t * allows much greater control over the the data that is being used to\n\t * order a column, but is necessarily therefore more complex.\n\t * \n\t * This type of ordering is useful if you want to do ordering based on data\n\t * live from the DOM (for example the contents of an 'input' element) rather\n\t * than just the static string that DataTables knows of.\n\t * \n\t * The way these plug-ins work is that you create an array of the values you\n\t * wish to be ordering for the column in question and then return that\n\t * array. The data in the array much be in the index order of the rows in\n\t * the table (not the currently ordering order!). Which order data gathering\n\t * function is run here depends on the `dt-init columns.orderDataType`\n\t * parameter that is used for the column (if any).\n\t *\n\t * The functions defined take two parameters:\n\t *\n\t * 1. `{object}` DataTables settings object: see\n\t * {@link DataTable.models.oSettings}\n\t * 2. `{int}` Target column index\n\t *\n\t * Each function is expected to return an array:\n\t *\n\t * * `{array}` Data for the column to be ordering upon\n\t *\n\t * @type array\n\t *\n\t * @example\n\t * // Ordering using `input` node values\n\t * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )\n\t * {\n\t * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\n\t * return $('input', td).val();\n\t * } );\n\t * }\n\t */\n\torder: {},\n\n\n\t/**\n\t * Type based plug-ins.\n\t *\n\t * Each column in DataTables has a type assigned to it, either by automatic\n\t * detection or by direct assignment using the `type` option for the column.\n\t * The type of a column will effect how it is ordering and search (plug-ins\n\t * can also make use of the column type if required).\n\t *\n\t * @namespace\n\t */\n\ttype: {\n\t\t/**\n\t\t * Type detection functions.\n\t\t *\n\t\t * The functions defined in this object are used to automatically detect\n\t\t * a column's type, making initialisation of DataTables super easy, even\n\t\t * when complex data is in the table.\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t * 1. `{*}` Data from the column cell to be analysed\n\t * 2. `{settings}` DataTables settings object. This can be used to\n\t * perform context specific type detection - for example detection\n\t * based on language settings such as using a comma for a decimal\n\t * place. Generally speaking the options from the settings will not\n\t * be required\n\t\t *\n\t\t * Each function is expected to return:\n\t\t *\n\t\t * * `{string|null}` Data type detected, or null if unknown (and thus\n\t\t * pass it on to the other type detection functions.\n\t\t *\n\t\t * @type array\n\t\t *\n\t\t * @example\n\t\t * // Currency type detection plug-in:\n\t\t * $.fn.dataTable.ext.type.detect.push(\n\t\t * function ( data, settings ) {\n\t\t * // Check the numeric part\n\t\t * if ( ! data.substring(1).match(/[0-9]/) ) {\n\t\t * return null;\n\t\t * }\n\t\t *\n\t\t * // Check prefixed by currency\n\t\t * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {\n\t\t * return 'currency';\n\t\t * }\n\t\t * return null;\n\t\t * }\n\t\t * );\n\t\t */\n\t\tdetect: [],\n\n\n\t\t/**\n\t\t * Type based search formatting.\n\t\t *\n\t\t * The type based searching functions can be used to pre-format the\n\t\t * data to be search on. For example, it can be used to strip HTML\n\t\t * tags or to de-format telephone numbers for numeric only searching.\n\t\t *\n\t\t * Note that is a search is not defined for a column of a given type,\n\t\t * no search formatting will be performed.\n\t\t * \n\t\t * Pre-processing of searching data plug-ins - When you assign the sType\n\t\t * for a column (or have it automatically detected for you by DataTables\n\t\t * or a type detection plug-in), you will typically be using this for\n\t\t * custom sorting, but it can also be used to provide custom searching\n\t\t * by allowing you to pre-processing the data and returning the data in\n\t\t * the format that should be searched upon. This is done by adding\n\t\t * functions this object with a parameter name which matches the sType\n\t\t * for that target column. This is the corollary of afnSortData\n\t\t * for searching data.\n\t\t *\n\t\t * The functions defined take a single parameter:\n\t\t *\n\t * 1. `{*}` Data from the column cell to be prepared for searching\n\t\t *\n\t\t * Each function is expected to return:\n\t\t *\n\t\t * * `{string|null}` Formatted string that will be used for the searching.\n\t\t *\n\t\t * @type object\n\t\t * @default {}\n\t\t *\n\t\t * @example\n\t\t * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\n\t\t * return d.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n\t\t * }\n\t\t */\n\t\tsearch: {},\n\n\n\t\t/**\n\t\t * Type based ordering.\n\t\t *\n\t\t * The column type tells DataTables what ordering to apply to the table\n\t\t * when a column is sorted upon. The order for each type that is defined,\n\t\t * is defined by the functions available in this object.\n\t\t *\n\t\t * Each ordering option can be described by three properties added to\n\t\t * this object:\n\t\t *\n\t\t * * `{type}-pre` - Pre-formatting function\n\t\t * * `{type}-asc` - Ascending order function\n\t\t * * `{type}-desc` - Descending order function\n\t\t *\n\t\t * All three can be used together, only `{type}-pre` or only\n\t\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\n\t\t * that only `{type}-pre` is used, as this provides the optimal\n\t\t * implementation in terms of speed, although the others are provided\n\t\t * for compatibility with existing Javascript sort functions.\n\t\t *\n\t\t * `{type}-pre`: Functions defined take a single parameter:\n\t\t *\n\t * 1. `{*}` Data from the column cell to be prepared for ordering\n\t\t *\n\t\t * And return:\n\t\t *\n\t\t * * `{*}` Data to be sorted upon\n\t\t *\n\t\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\n\t\t * functions, taking two parameters:\n\t\t *\n\t * 1. `{*}` Data to compare to the second parameter\n\t * 2. `{*}` Data to compare to the first parameter\n\t\t *\n\t\t * And returning:\n\t\t *\n\t\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\n\t\t * than the second parameter, ===0 if the two parameters are equal and\n\t\t * >0 if the first parameter should be sorted height than the second\n\t\t * parameter.\n\t\t * \n\t\t * @type object\n\t\t * @default {}\n\t\t *\n\t\t * @example\n\t\t * // Numeric ordering of formatted numbers with a pre-formatter\n\t\t * $.extend( $.fn.dataTable.ext.type.order, {\n\t\t * \"string-pre\": function(x) {\n\t\t * a = (a === \"-\" || a === \"\") ? 0 : a.replace( /[^\\d\\-\\.]/g, \"\" );\n\t\t * return parseFloat( a );\n\t\t * }\n\t\t * } );\n\t\t *\n\t\t * @example\n\t\t * // Case-sensitive string ordering, with no pre-formatting method\n\t\t * $.extend( $.fn.dataTable.ext.order, {\n\t\t * \"string-case-asc\": function(x,y) {\n\t\t * return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t * },\n\t\t * \"string-case-desc\": function(x,y) {\n\t\t * return ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t * }\n\t\t * } );\n\t\t */\n\t\torder: {}\n\t},\n\n\t/**\n\t * Unique DataTables instance counter\n\t *\n\t * @type int\n\t * @private\n\t */\n\t_unique: 0,\n\n\n\t//\n\t// Depreciated\n\t// The following properties are retained for backwards compatibility only.\n\t// The should not be used in new projects and will be removed in a future\n\t// version\n\t//\n\n\t/**\n\t * Version check function.\n\t * @type function\n\t * @depreciated Since 1.10\n\t */\n\tfnVersionCheck: DataTable.fnVersionCheck,\n\n\n\t/**\n\t * Index for what 'this' index API functions should use\n\t * @type int\n\t * @deprecated Since v1.10\n\t */\n\tiApiIndex: 0,\n\n\n\t/**\n\t * jQuery UI class container\n\t * @type object\n\t * @deprecated Since v1.10\n\t */\n\toJUIClasses: {},\n\n\n\t/**\n\t * Software version\n\t * @type string\n\t * @deprecated Since v1.10\n\t */\n\tsVersion: DataTable.version\n};\n\n\n//\n// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\n//\n$.extend( _ext, {\n\tafnFiltering: _ext.search,\n\taTypes: _ext.type.detect,\n\tofnSearch: _ext.type.search,\n\toSort: _ext.type.order,\n\tafnSortData: _ext.order,\n\taoFeatures: _ext.feature,\n\toApi: _ext.internal,\n\toStdClasses: _ext.classes,\n\toPagination: _ext.pager\n} );\n\n\n$.extend( DataTable.ext.classes, {\n\t\"sTable\": \"dataTable\",\n\t\"sNoFooter\": \"no-footer\",\n\n\t/* Paging buttons */\n\t\"sPageButton\": \"paginate_button\",\n\t\"sPageButtonActive\": \"current\",\n\t\"sPageButtonDisabled\": \"disabled\",\n\n\t/* Striping classes */\n\t\"sStripeOdd\": \"odd\",\n\t\"sStripeEven\": \"even\",\n\n\t/* Empty row */\n\t\"sRowEmpty\": \"dataTables_empty\",\n\n\t/* Features */\n\t\"sWrapper\": \"dataTables_wrapper\",\n\t\"sFilter\": \"dataTables_filter\",\n\t\"sInfo\": \"dataTables_info\",\n\t\"sPaging\": \"dataTables_paginate paging_\", /* Note that the type is postfixed */\n\t\"sLength\": \"dataTables_length\",\n\t\"sProcessing\": \"dataTables_processing\",\n\n\t/* Sorting */\n\t\"sSortAsc\": \"sorting_asc\",\n\t\"sSortDesc\": \"sorting_desc\",\n\t\"sSortable\": \"sorting\", /* Sortable in both directions */\n\t\"sSortableAsc\": \"sorting_desc_disabled\",\n\t\"sSortableDesc\": \"sorting_asc_disabled\",\n\t\"sSortableNone\": \"sorting_disabled\",\n\t\"sSortColumn\": \"sorting_\", /* Note that an int is postfixed for the sorting order */\n\n\t/* Filtering */\n\t\"sFilterInput\": \"\",\n\n\t/* Page length */\n\t\"sLengthSelect\": \"\",\n\n\t/* Scrolling */\n\t\"sScrollWrapper\": \"dataTables_scroll\",\n\t\"sScrollHead\": \"dataTables_scrollHead\",\n\t\"sScrollHeadInner\": \"dataTables_scrollHeadInner\",\n\t\"sScrollBody\": \"dataTables_scrollBody\",\n\t\"sScrollFoot\": \"dataTables_scrollFoot\",\n\t\"sScrollFootInner\": \"dataTables_scrollFootInner\",\n\n\t/* Misc */\n\t\"sHeaderTH\": \"\",\n\t\"sFooterTH\": \"\",\n\n\t// Deprecated\n\t\"sSortJUIAsc\": \"\",\n\t\"sSortJUIDesc\": \"\",\n\t\"sSortJUI\": \"\",\n\t\"sSortJUIAscAllowed\": \"\",\n\t\"sSortJUIDescAllowed\": \"\",\n\t\"sSortJUIWrapper\": \"\",\n\t\"sSortIcon\": \"\",\n\t\"sJUIHeader\": \"\",\n\t\"sJUIFooter\": \"\"\n} );\n\n\nvar extPagination = DataTable.ext.pager;\n\nfunction _numbers ( page, pages ) {\n\tvar\n\t\tnumbers = [],\n\t\tbuttons = extPagination.numbers_length,\n\t\thalf = Math.floor( buttons / 2 ),\n\t\ti = 1;\n\n\tif ( pages <= buttons ) {\n\t\tnumbers = _range( 0, pages );\n\t}\n\telse if ( page <= half ) {\n\t\tnumbers = _range( 0, buttons-2 );\n\t\tnumbers.push( 'ellipsis' );\n\t\tnumbers.push( pages-1 );\n\t}\n\telse if ( page >= pages - 1 - half ) {\n\t\tnumbers = _range( pages-(buttons-2), pages );\n\t\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\n\t\tnumbers.splice( 0, 0, 0 );\n\t}\n\telse {\n\t\tnumbers = _range( page-half+2, page+half-1 );\n\t\tnumbers.push( 'ellipsis' );\n\t\tnumbers.push( pages-1 );\n\t\tnumbers.splice( 0, 0, 'ellipsis' );\n\t\tnumbers.splice( 0, 0, 0 );\n\t}\n\n\tnumbers.DT_el = 'span';\n\treturn numbers;\n}\n\n\n$.extend( extPagination, {\n\tsimple: function ( page, pages ) {\n\t\treturn [ 'previous', 'next' ];\n\t},\n\n\tfull: function ( page, pages ) {\n\t\treturn [ 'first', 'previous', 'next', 'last' ];\n\t},\n\n\tnumbers: function ( page, pages ) {\n\t\treturn [ _numbers(page, pages) ];\n\t},\n\n\tsimple_numbers: function ( page, pages ) {\n\t\treturn [ 'previous', _numbers(page, pages), 'next' ];\n\t},\n\n\tfull_numbers: function ( page, pages ) {\n\t\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\n\t},\n\t\n\tfirst_last_numbers: function (page, pages) {\n \t\treturn ['first', _numbers(page, pages), 'last'];\n \t},\n\n\t// For testing and plug-ins to use\n\t_numbers: _numbers,\n\n\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\n\tnumbers_length: 7\n} );\n\n\n$.extend( true, DataTable.ext.renderer, {\n\tpageButton: {\n\t\t_: function ( settings, host, idx, buttons, page, pages ) {\n\t\t\tvar classes = settings.oClasses;\n\t\t\tvar lang = settings.oLanguage.oPaginate;\n\t\t\tvar aria = settings.oLanguage.oAria.paginate || {};\n\t\t\tvar btnDisplay, btnClass;\n\n\t\t\tvar attach = function( container, buttons ) {\n\t\t\t\tvar i, ien, node, button;\n\t\t\t\tvar disabledClass = classes.sPageButtonDisabled;\n\t\t\t\tvar clickHandler = function ( e ) {\n\t\t\t\t\t_fnPageChange( settings, e.data.action, true );\n\t\t\t\t};\n\n\t\t\t\tfor ( i=0, ien=buttons.length ; i' )\n\t\t\t\t\t\t\t.appendTo( container );\n\t\t\t\t\t\tattach( inner, button );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar disabled = false;\n\n\t\t\t\t\t\tbtnDisplay = null;\n\t\t\t\t\t\tbtnClass = button;\n\n\t\t\t\t\t\tswitch ( button ) {\n\t\t\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\t\t\tcontainer.append('…');\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'first':\n\t\t\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\n\t\t\t\t\t\t\t\tif ( page === 0 ) {\n\t\t\t\t\t\t\t\t\tdisabled = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\n\t\t\t\t\t\t\t\tif ( page === 0 ) {\n\t\t\t\t\t\t\t\t\tdisabled = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\n\t\t\t\t\t\t\t\tif ( pages === 0 || page === pages-1 ) {\n\t\t\t\t\t\t\t\t\tdisabled = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'last':\n\t\t\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\n\t\t\t\t\t\t\t\tif ( pages === 0 || page === pages-1 ) {\n\t\t\t\t\t\t\t\t\tdisabled = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tbtnDisplay = settings.fnFormatNumber( button + 1 );\n\t\t\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t\t\tclasses.sPageButtonActive : '';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( btnDisplay !== null ) {\n\t\t\t\t\t\t\tvar tag = settings.oInit.pagingTag || 'a';\n\n\t\t\t\t\t\t\tif (disabled) {\n\t\t\t\t\t\t\t\tbtnClass += ' ' + disabledClass;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnode = $('<'+tag+'>', {\n\t\t\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t\t'aria-disabled': disabled ? 'true' : null,\n\t\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t\t'role': 'link',\n\t\t\t\t\t\t\t\t\t'aria-current': btnClass === classes.sPageButtonActive ? 'page' : null,\n\t\t\t\t\t\t\t\t\t'data-dt-idx': button,\n\t\t\t\t\t\t\t\t\t'tabindex': disabled ? -1 : settings.iTabIndex,\n\t\t\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\t\t\t_fnBindAction(\n\t\t\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t// inside an iframe or frame. Try / catch the error. Not good for\n\t\t\t// accessibility, but neither are frames.\n\t\t\tvar activeEl;\n\n\t\t\ttry {\n\t\t\t\t// Because this approach is destroying and recreating the paging\n\t\t\t\t// elements, focus is lost on the select button which is bad for\n\t\t\t\t// accessibility. So we want to restore focus once the draw has\n\t\t\t\t// completed\n\t\t\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t\t\t}\n\t\t\tcatch (e) {}\n\n\t\t\tattach( $(host).empty(), buttons );\n\n\t\t\tif ( activeEl !== undefined ) {\n\t\t\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');\n\t\t\t}\n\t\t}\n\t}\n} );\n\n\n\n// Built in type detection. See model.ext.aTypes for information about\n// what is required from this methods.\n$.extend( DataTable.ext.type.detect, [\n\t// Plain numbers - first since V8 detects some plain numbers as dates\n\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\n\tfunction ( d, settings )\n\t{\n\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\n\t},\n\n\t// Dates (only those recognised by the browser's Date.parse)\n\tfunction ( d, settings )\n\t{\n\t\t// V8 tries _very_ hard to make a string passed into `Date.parse()`\n\t\t// valid, so we need to use a regex to restrict date formats. Use a\n\t\t// plug-in for anything other than ISO8601 style strings\n\t\tif ( d && !(d instanceof Date) && ! _re_date.test(d) ) {\n\t\t\treturn null;\n\t\t}\n\t\tvar parsed = Date.parse(d);\n\t\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\n\t},\n\n\t// Formatted numbers\n\tfunction ( d, settings )\n\t{\n\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\n\t},\n\n\t// HTML numeric\n\tfunction ( d, settings )\n\t{\n\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\n\t},\n\n\t// HTML numeric, formatted\n\tfunction ( d, settings )\n\t{\n\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\n\t},\n\n\t// HTML (this is strict checking - there must be html)\n\tfunction ( d, settings )\n\t{\n\t\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\n\t\t\t'html' : null;\n\t}\n] );\n\n\n\n// Filter formatting functions. See model.ext.ofnSearch for information about\n// what is required from these methods.\n// \n// Note that additional search methods are added for the html numbers and\n// html formatted numbers by `_addNumericSort()` when we know what the decimal\n// place is\n\n\n$.extend( DataTable.ext.type.search, {\n\thtml: function ( data ) {\n\t\treturn _empty(data) ?\n\t\t\tdata :\n\t\t\ttypeof data === 'string' ?\n\t\t\t\tdata\n\t\t\t\t\t.replace( _re_new_lines, \" \" )\n\t\t\t\t\t.replace( _re_html, \"\" ) :\n\t\t\t\t'';\n\t},\n\n\tstring: function ( data ) {\n\t\treturn _empty(data) ?\n\t\t\tdata :\n\t\t\ttypeof data === 'string' ?\n\t\t\t\tdata.replace( _re_new_lines, \" \" ) :\n\t\t\t\tdata;\n\t}\n} );\n\n\n\nvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\n\tif ( d !== 0 && (!d || d === '-') ) {\n\t\treturn -Infinity;\n\t}\n\t\n\tvar type = typeof d;\n\n\tif (type === 'number' || type === 'bigint') {\n\t\treturn d;\n\t}\n\n\t// If a decimal place other than `.` is used, it needs to be given to the\n\t// function so we can detect it and replace with a `.` which is the only\n\t// decimal place Javascript recognises - it is not locale aware.\n\tif ( decimalPlace ) {\n\t\td = _numToDecimal( d, decimalPlace );\n\t}\n\n\tif ( d.replace ) {\n\t\tif ( re1 ) {\n\t\t\td = d.replace( re1, '' );\n\t\t}\n\n\t\tif ( re2 ) {\n\t\t\td = d.replace( re2, '' );\n\t\t}\n\t}\n\n\treturn d * 1;\n};\n\n\n// Add the numeric 'deformatting' functions for sorting and search. This is done\n// in a function to provide an easy ability for the language options to add\n// additional methods if a non-period decimal place is used.\nfunction _addNumericSort ( decimalPlace ) {\n\t$.each(\n\t\t{\n\t\t\t// Plain numbers\n\t\t\t\"num\": function ( d ) {\n\t\t\t\treturn __numericReplace( d, decimalPlace );\n\t\t\t},\n\n\t\t\t// Formatted numbers\n\t\t\t\"num-fmt\": function ( d ) {\n\t\t\t\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\n\t\t\t},\n\n\t\t\t// HTML numeric\n\t\t\t\"html-num\": function ( d ) {\n\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html );\n\t\t\t},\n\n\t\t\t// HTML numeric, formatted\n\t\t\t\"html-num-fmt\": function ( d ) {\n\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\n\t\t\t}\n\t\t},\n\t\tfunction ( key, fn ) {\n\t\t\t// Add the ordering method\n\t\t\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\n\n\t\t\t// For HTML types add a search formatter that will strip the HTML\n\t\t\tif ( key.match(/^html\\-/) ) {\n\t\t\t\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\n\t\t\t}\n\t\t}\n\t);\n}\n\n\n// Default sort methods\n$.extend( _ext.type.order, {\n\t// Dates\n\t\"date-pre\": function ( d ) {\n\t\tvar ts = Date.parse( d );\n\t\treturn isNaN(ts) ? -Infinity : ts;\n\t},\n\n\t// html\n\t\"html-pre\": function ( a ) {\n\t\treturn _empty(a) ?\n\t\t\t'' :\n\t\t\ta.replace ?\n\t\t\t\ta.replace( /<.*?>/g, \"\" ).toLowerCase() :\n\t\t\t\ta+'';\n\t},\n\n\t// string\n\t\"string-pre\": function ( a ) {\n\t\t// This is a little complex, but faster than always calling toString,\n\t\t// https://jsperf.com/tostring-v-check\n\t\treturn _empty(a) ?\n\t\t\t'' :\n\t\t\ttypeof a === 'string' ?\n\t\t\t\ta.toLowerCase() :\n\t\t\t\t! a.toString ?\n\t\t\t\t\t'' :\n\t\t\t\t\ta.toString();\n\t},\n\n\t// string-asc and -desc are retained only for compatibility with the old\n\t// sort methods\n\t\"string-asc\": function ( x, y ) {\n\t\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t},\n\n\t\"string-desc\": function ( x, y ) {\n\t\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t}\n} );\n\n\n// Numeric sorting types - order doesn't matter here\n_addNumericSort( '' );\n\n\n$.extend( true, DataTable.ext.renderer, {\n\theader: {\n\t\t_: function ( settings, cell, column, classes ) {\n\t\t\t// No additional mark-up required\n\t\t\t// Attach a sort listener to update on sort - note that using the\n\t\t\t// `DT` namespace will allow the event to be removed automatically\n\t\t\t// on destroy, while the `dt` namespaced event is the one we are\n\t\t\t// listening for\n\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\tif ( settings !== ctx ) { // need to check this this is the host\n\t\t\t\t\treturn; // table, not a nested one\n\t\t\t\t}\n\n\t\t\t\tvar colIdx = column.idx;\n\n\t\t\t\tcell\n\t\t\t\t\t.removeClass(\n\t\t\t\t\t\tclasses.sSortAsc +' '+\n\t\t\t\t\t\tclasses.sSortDesc\n\t\t\t\t\t)\n\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t);\n\t\t\t} );\n\t\t},\n\n\t\tjqueryui: function ( settings, cell, column, classes ) {\n\t\t\t$('')\n\t\t\t\t.addClass( classes.sSortJUIWrapper )\n\t\t\t\t.append( cell.contents() )\n\t\t\t\t.append( $('')\n\t\t\t\t\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\n\t\t\t\t)\n\t\t\t\t.appendTo( cell );\n\n\t\t\t// Attach a sort listener to update on sort\n\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar colIdx = column.idx;\n\n\t\t\t\tcell\n\t\t\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t);\n\n\t\t\t\tcell\n\t\t\t\t\t.find( 'span.'+classes.sSortIcon )\n\t\t\t\t\t.removeClass(\n\t\t\t\t\t\tclasses.sSortJUIAsc +\" \"+\n\t\t\t\t\t\tclasses.sSortJUIDesc +\" \"+\n\t\t\t\t\t\tclasses.sSortJUI +\" \"+\n\t\t\t\t\t\tclasses.sSortJUIAscAllowed +\" \"+\n\t\t\t\t\t\tclasses.sSortJUIDescAllowed\n\t\t\t\t\t)\n\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\tclasses.sSortJUIDesc :\n\t\t\t\t\t\t\tcolumn.sSortingClassJUI\n\t\t\t\t\t);\n\t\t\t} );\n\t\t}\n\t}\n} );\n\n/*\n * Public helper functions. These aren't used internally by DataTables, or\n * called by any of the options passed into DataTables, but they can be used\n * externally by developers working with DataTables. They are helper functions\n * to make working with DataTables a little bit easier.\n */\n\nvar __htmlEscapeEntities = function ( d ) {\n\tif (Array.isArray(d)) {\n\t\td = d.join(',');\n\t}\n\n\treturn typeof d === 'string' ?\n\t\td\n\t\t\t.replace(/&/g, '&')\n\t\t\t.replace(//g, '>')\n\t\t\t.replace(/\"/g, '"') :\n\t\td;\n};\n\n// Common logic for moment, luxon or a date action\nfunction __mld( dt, momentFn, luxonFn, dateFn, arg1 ) {\n\tif (window.moment) {\n\t\treturn dt[momentFn]( arg1 );\n\t}\n\telse if (window.luxon) {\n\t\treturn dt[luxonFn]( arg1 );\n\t}\n\t\n\treturn dateFn ? dt[dateFn]( arg1 ) : dt;\n}\n\n\nvar __mlWarning = false;\nfunction __mldObj (d, format, locale) {\n\tvar dt;\n\n\tif (window.moment) {\n\t\tdt = window.moment.utc( d, format, locale, true );\n\n\t\tif (! dt.isValid()) {\n\t\t\treturn null;\n\t\t}\n\t}\n\telse if (window.luxon) {\n\t\tdt = format && typeof d === 'string'\n\t\t\t? window.luxon.DateTime.fromFormat( d, format )\n\t\t\t: window.luxon.DateTime.fromISO( d );\n\n\t\tif (! dt.isValid) {\n\t\t\treturn null;\n\t\t}\n\n\t\tdt.setLocale(locale);\n\t}\n\telse if (! format) {\n\t\t// No format given, must be ISO\n\t\tdt = new Date(d);\n\t}\n\telse {\n\t\tif (! __mlWarning) {\n\t\t\talert('DataTables warning: Formatted date without Moment.js or Luxon - https://datatables.net/tn/17');\n\t\t}\n\n\t\t__mlWarning = true;\n\t}\n\n\treturn dt;\n}\n\n// Wrapper for date, datetime and time which all operate the same way with the exception of\n// the output string for auto locale support\nfunction __mlHelper (localeString) {\n\treturn function ( from, to, locale, def ) {\n\t\t// Luxon and Moment support\n\t\t// Argument shifting\n\t\tif ( arguments.length === 0 ) {\n\t\t\tlocale = 'en';\n\t\t\tto = null; // means toLocaleString\n\t\t\tfrom = null; // means iso8601\n\t\t}\n\t\telse if ( arguments.length === 1 ) {\n\t\t\tlocale = 'en';\n\t\t\tto = from;\n\t\t\tfrom = null;\n\t\t}\n\t\telse if ( arguments.length === 2 ) {\n\t\t\tlocale = to;\n\t\t\tto = from;\n\t\t\tfrom = null;\n\t\t}\n\n\t\tvar typeName = 'datetime-' + to;\n\n\t\t// Add type detection and sorting specific to this date format - we need to be able to identify\n\t\t// date type columns as such, rather than as numbers in extensions. Hence the need for this.\n\t\tif (! DataTable.ext.type.order[typeName]) {\n\t\t\t// The renderer will give the value to type detect as the type!\n\t\t\tDataTable.ext.type.detect.unshift(function (d) {\n\t\t\t\treturn d === typeName ? typeName : false;\n\t\t\t});\n\n\t\t\t// The renderer gives us Moment, Luxon or Date obects for the sorting, all of which have a\n\t\t\t// `valueOf` which gives milliseconds epoch\n\t\t\tDataTable.ext.type.order[typeName + '-asc'] = function (a, b) {\n\t\t\t\tvar x = a.valueOf();\n\t\t\t\tvar y = b.valueOf();\n\n\t\t\t\treturn x === y\n\t\t\t\t\t? 0\n\t\t\t\t\t: x < y\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: 1;\n\t\t\t}\n\n\t\t\tDataTable.ext.type.order[typeName + '-desc'] = function (a, b) {\n\t\t\t\tvar x = a.valueOf();\n\t\t\t\tvar y = b.valueOf();\n\n\t\t\t\treturn x === y\n\t\t\t\t\t? 0\n\t\t\t\t\t: x > y\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: 1;\n\t\t\t}\n\t\t}\n\t\n\t\treturn function ( d, type ) {\n\t\t\t// Allow for a default value\n\t\t\tif (d === null || d === undefined) {\n\t\t\t\tif (def === '--now') {\n\t\t\t\t\t// We treat everything as UTC further down, so no changes are\n\t\t\t\t\t// made, as such need to get the local date / time as if it were\n\t\t\t\t\t// UTC\n\t\t\t\t\tvar local = new Date();\n\t\t\t\t\td = new Date( Date.UTC(\n\t\t\t\t\t\tlocal.getFullYear(), local.getMonth(), local.getDate(),\n\t\t\t\t\t\tlocal.getHours(), local.getMinutes(), local.getSeconds()\n\t\t\t\t\t) );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\td = '';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (type === 'type') {\n\t\t\t\t// Typing uses the type name for fast matching\n\t\t\t\treturn typeName;\n\t\t\t}\n\n\t\t\tif (d === '') {\n\t\t\t\treturn type !== 'sort'\n\t\t\t\t\t? ''\n\t\t\t\t\t: __mldObj('0000-01-01 00:00:00', null, locale);\n\t\t\t}\n\n\t\t\t// Shortcut. If `from` and `to` are the same, we are using the renderer to\n\t\t\t// format for ordering, not display - its already in the display format.\n\t\t\tif ( to !== null && from === to && type !== 'sort' && type !== 'type' && ! (d instanceof Date) ) {\n\t\t\t\treturn d;\n\t\t\t}\n\n\t\t\tvar dt = __mldObj(d, from, locale);\n\n\t\t\tif (dt === null) {\n\t\t\t\treturn d;\n\t\t\t}\n\n\t\t\tif (type === 'sort') {\n\t\t\t\treturn dt;\n\t\t\t}\n\t\t\t\n\t\t\tvar formatted = to === null\n\t\t\t\t? __mld(dt, 'toDate', 'toJSDate', '')[localeString]()\n\t\t\t\t: __mld(dt, 'format', 'toFormat', 'toISOString', to);\n\n\t\t\t// XSS protection\n\t\t\treturn type === 'display' ?\n\t\t\t\t__htmlEscapeEntities( formatted ) :\n\t\t\t\tformatted;\n\t\t};\n\t}\n}\n\n// Based on locale, determine standard number formatting\n// Fallback for legacy browsers is US English\nvar __thousands = ',';\nvar __decimal = '.';\n\nif (window.Intl !== undefined) {\n\ttry {\n\t\tvar num = new Intl.NumberFormat().formatToParts(100000.1);\n\t\n\t\tfor (var i=0 ; i<'col-sm-12 col-md-6'f>>\" +\n\t\t\"<'row dt-row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper: \"dataTables_wrapper dt-bootstrap5\",\n\tsFilterInput: \"form-control form-control-sm\",\n\tsLengthSelect: \"form-select form-select-sm\",\n\tsProcessing: \"dataTables_processing card\",\n\tsPageButton: \"paginate_button page-item\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tvar disabled = btnClass.indexOf('disabled') !== -1;\n\n\t\t\t\t\tnode = $('