
(function() {

var escapeHtml = function (str) {
	return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};

var Dom = null;

document.addEventListener('DOMContentLoaded', () => {
	if (window.DataTable) {
		Dom = DataTable.Dom;
	}
});

window.dt_demo = {
	/**
	 * Initialise the example
	 *
	 * @param types Init code
	 */
	init: function (types) {
		if (types) {
			dt_demo._struct = types;

			dt_demo._prepLibs();
		}

		dt_demo._loadNext();
	},

	_prepLibs: function () {
		var initStyle = dt_demo.storage.get('dt-demo-style') || 'datatables';
		var libs = dt_demo._struct.libs;
		var framework = initStyle;

		if (libs.targetFramework) {
			initStyle = libs.targetFramework;
			framework = libs.targetFramework;
		}

		if (framework !== 'datatables') {
			dt_demo._addLib(framework, 'css');
		}

		if (framework === 'bulma') {
			dt_demo._addLib('font-awesome', 'css');
		}

		for (var i = 0; i < libs.css.length; i++) {
			dt_demo._addLib(libs.css[i], 'css', framework);
		}

		// We need to load jQuery if we are using a styling framework that has
		// it as a dependency for them, and it needs to load before them.
		if (
			initStyle === 'bootstrap' ||
			initStyle === 'bootstrap4' ||
			initStyle === 'foundation' ||
			initStyle === 'jqueryui' ||
			initStyle === 'semanticui'
		) {
			dt_demo._addLib('jquery', 'js');
		}

		if (framework !== 'datatables') {
			dt_demo._addLib(framework, 'js');
		}

		for (var i = 0; i < libs.js.length; i++) {
			dt_demo._addLib(libs.js[i], 'js', framework);
		}
	},

	_addLib: function (libName, type, framework) {
		var types = dt_demo._struct;

		if (libName.indexOf('//') === 0 || libName.indexOf('https://') === 0) {
			src = libName;
		}
		else if (libName.indexOf('feature-') === 0) {
			src = dt_demo._appendFileName(
				libName.replace('feature-', ''),
				'..',
				type,
				'datatables'
			);
		}
		else {
			var lib = types.libs.components[libName];
			var src = lib[type];

			if (lib.resolve) {
				src = dt_demo._appendFileName(libName, src, type, framework);
			}
		}

		if (src) {
			src.split('|').forEach(url => {
				dt_demo._loadQueue.push({
					name: libName,
					type: type,
					src: url
				});
			});
		}
	},

	_highlightElement: function (selector, text) {
		let el = Dom.s(selector);

		if (el.length && text) {
			el
				.empty()
				.attrRemove('data-highlighted')
				.text(text);
		}

		if (el.length && el.attr('data-highlighted') !== 'yes') {
			hljs.highlightElement(el.get(0));
		}
	},

	_tabs: function () {
		if (
			Dom.s('div.dt-tabs').length &&
			(
				Dom.s('body').classHas('example') ||
				Dom.s('body').classHas('dt-example')
			)
		) {
			// js
			dt_demo._displayFiles('#js-lib-files', dt_demo._loaded.js);
			dt_demo._displayFiles('#css-lib-files', dt_demo._loaded.css);

			dt_demo._highlightElement('div.js code');

			// css
			var cssContainer = Dom.s('div.dt-tabs div.css');
			if (cssContainer.find('code').text() === '') {
				cssContainer.find('code, div').css('display', 'none');
				cssContainer.find('p').eq(0).css('display', 'none');
			}

			dt_demo._highlightElement('div.css code');

			// This can really slow things down
			setTimeout(function () {
				dt_demo._highlightElement('div.table code');
			}, 1000);

			// json
			var ajaxTab = Dom.s('ul.dt-tabs li').eq(3).css('display', 'none');

			Dom.s(document).on('init.dt', function (e, settings) {
				if (e.namespace !== 'dt') {
					return;
				}

				var api = new DataTable.Api(settings);

				var show = function (str) {
					ajaxTab.css('display', 'block');
					Dom.s('div.dt-tabs div.ajax code').remove();
					// Dom.s('div.dt-tabs div.ajax div.syntaxhighlighter').remove();

					// Old IE :-|
					try {
						str = JSON.stringify(str, null, 2);
					} catch (e) {}

					var strArr = str.split('\n');

					if (strArr.length > 1000) {
						var first = strArr.splice(0, 500);
						var second = strArr.splice(strArr.length - 499, 499);
						first.push(
							"\n\n... Truncated for brevity - look at your browser's network inspector to see the full source ...\n\n"
						);
						str = first.concat(second).join('\n');
					}

					Dom
						.s('div.dt-tabs div.ajax')
						.append(Dom.c('code').classAdd('multiline language-js').text(str));

					// This can be really slow for large builds
					setTimeout(function () {
						dt_demo._highlightElement('div.dt-tabs div.ajax code');
					}, 10);
				};

				// First draw
				var json = api.ajax.json();
				if (json) {
					show(json);
				}

				// Subsequent draws
				api.on('xhr.dt', function (e, settings, json) {
					show(json);
				});
			});

			// php
			var phpTab = Dom.s('ul.dt-tabs li').eq(4).css('display', 'none');

			Dom.s(document).on('init.dt.demoSSP', function (e, settings) {
				if (e.namespace !== 'dt') {
					return;
				}

				// Editor's demo has its own call to do this
				if (DataTable && DataTable.Editor) {
					return;
				}

				if (settings.features.serverSide) {
					if (typeof settings.ajax === 'function') {
						return;
					}

					DataTable.ajax({
						url: '../resources/examples.php',
						data: {
							src: settings.ajaxSource || settings.ajax.url || settings.ajax
						},
						dataType: 'text',
						type: 'post',
						success: function (txt) {
							phpTab.css('display', 'block');
							Dom
								.s('div.dt-tabs div.php')
								.append(
									Dom.c('code').classAdd('multiline language-php').text(txt)
								);

							dt_demo._highlightElement('div.dt-tabs div.php code');
						}
					});
				}
			});
		}

		// Tabs
		Dom.s('ul.dt-tabs').on('click', 'li:not(.disabled)', function () {
			Dom.s('ul.dt-tabs li.active').classRemove('active');
			Dom.s(this).classAdd('active');

			Dom
				.s('div.dt-tabs>div')
				.css('display', 'none')
				.eq(Dom.s(this).index())
				.css('display', 'block');
		});
		Dom.s('ul.dt-tabs li.active').trigger('click');
	},

	_appendFileName: function (name, src, type, framework) {
		var out = [];
		var fileName = dt_demo._getFileName(name);
		var fwFile = dt_demo._getFrameworkFile(framework);
		var min = dt_demo._struct.min ? 'min.' : '';

		// Plugins use a relative path, and don't separate by styling framework
		if (type === 'js' || src === '..') {
			if (name === 'datatables') {
				out.push(src + '/dataTables.' + min + type);
			}
			else {
				out.push(src + '/dataTables.' + fileName + '.' + min + type);
			}
		}

		if (
			src === '..' ||
			(type === 'js' && framework === 'datatables' && name === 'datatables')
		) {
			// noop
		}
		else {
			out.push(src + '/' + fileName + '.' + fwFile + '.' + min + type);
		}

		return out.join('|');
	},

	_loadNext: function (source) {
		var queue = dt_demo._loadQueue;
		var cssQueue = dt_demo._loadCssQueue;

		// Check if all libraries have been loaded
		if (queue.length === 0 && cssQueue.length === 0) {
			// Check the document is ready
			if (document.readyState === 'complete') {
				dt_demo._run();
			}
			else if (document.readyState === 'interactive') {
				document.addEventListener('readystatechange', event => {
					if (queue.length === 0 && cssQueue.length === 0) {
						dt_demo._run();
					}
				});
			}
			else {
				document.addEventListener('DOMContentLoaded', function () {
					if (queue.length === 0 && cssQueue.length === 0) {
						dt_demo._run();
					}
				});
			}

			return;
		}

		// The css source is just to run the above
		if (source === 'css') {
			return;
		}

		var item = queue.shift();

		if (!item) {
			return;
		}

		// Already got jQuery from an external source - spin on
		if (item.name === 'jquery' && window.jQuery) {
			dt_demo._loaded.js.push(item.src);
			dt_demo._loadNext();
			return;
		}
		else if (
			item.name === 'datatables' &&
			item.src.indexOf('dataTables.js') !== -1 &&
			window.DataTable
		) {
			// Likewise for DataTables
			dt_demo._loaded.js.push(item.src);
			dt_demo._loadNext();
			return;
		}

		if (item.type === 'css') {
			var script = document.createElement('link');
			script.href = item.src;
			script.rel = 'stylesheet';
			script.onload = function () {
				// We want to wait for all CSS to load, but not individually
				// like the JS, so the loading queue check is a little
				// different, here it removes items that were added so an empty
				// queue indicates all are loaded.
				var idx = cssQueue.indexOf(item.src);

				if (idx !== -1) {
					cssQueue.splice(idx, 1);
				}

				dt_demo._loadNext('css');
			};

			cssQueue.push(item.src);
			dt_demo._loaded.css.push(item.src);

			document.head.appendChild(script);
			dt_demo._loadNext(); // don't wait for the CSS
		}
		else {
			var script = document.createElement('script');
			script.src = item.src;
			script.type = 'text/javascript';
			script.onload = function () {
				// Tailwind specific config
				if (item.name === 'tailwindcss') {
					window.tailwind.config = { darkMode: 'class' };
				}
				else if (item.name === 'jquery' && window.cash) {
					window.jQuery = window.cash;
				}

				dt_demo._loadNext();
			};

			dt_demo._loaded.js.push(item.src);

			document.head.appendChild(script);
		}
	},

	_loadQueue: [],
	_loadCssQueue: [],
	_loaded: {
		css: [],
		js: []
	},

	storage: {
		// Allows compatibility with the DT site storage of preferences
		get: function (name) {
			return typeof getCookie === 'function'
				? getCookie(name)
				: localStorage.getItem(name);
		},

		set: function (name, val) {
			if (typeof setCookie === 'function') {
				setCookie(name, val);
			}
			else {
				localStorage.setItem(name, val);
			}
		}
	},

	/**
	 * Run example based on code available
	 */
	_run: function () {
		if (dt_demo.hasRun) {
			return;
		}

		dt_demo.hasRun = true;

		// Check DataTables has loaded. If not, don't do anything - the
		// remaining code depends on the DataTables dom library.
		if (!window.DataTable) {
			return;
		}

		Dom = DataTable.Dom;

		// init html
		var types = dt_demo._struct;
		var demoHtml = '';

		var event = new Event('dt-demo-run');
		document.dispatchEvent(event);

		dt_demo._editorExamples();

		if (Dom.s('div.demo-html').count()) {
			demoHtml = Dom.s('div.demo-html').html().trim();

			if (demoHtml) {
				demoHtml = demoHtml + '\n\n';
			}
		}

		let code = Dom
			.c('code')
			.classAdd('multiline language-html')
			.text('\t\t\t\t' + demoHtml);
		Dom.s('div.dt-tabs div.table').append(code);

		dt_demo._tabs();

		var optionsContainer = Dom.s('div.dt-demo-options');

		if (!optionsContainer.count()) {
			optionsContainer = Dom
				.c('div')
				.classAdd('dt-demo-options')
				.insertBefore(Dom.s('h1').get(0));
		}

		// Style selector
		var initStyle = dt_demo.storage.get('dt-demo-style') || 'datatables';

		// Show a warning if there is no script for this version
		if (types) {
			// Style library selector options
			dt_demo._options(
				'Styling framework',
				optionsContainer,
				[
					{
						label: 'Bootstrap 3',
						val: 'bootstrap'
					},
					{
						label: 'Bootstrap 4',
						val: 'bootstrap4'
					},
					{
						label: 'Bootstrap 5',
						val: 'bootstrap5'
					},
					{
						label: 'Bulma',
						val: 'bulma'
					},
					{
						label: 'DataTables',
						val: 'datatables'
					},
					{
						label: 'Foundation',
						val: 'foundation'
					},
					{
						label: 'jQuery UI',
						val: 'jqueryui'
					},
					{
						label: 'Fomantic UI',
						val: 'semanticui'
					}
				],
				initStyle,
				function (option, container, initStyle) {
					dt_demo.storage.set('dt-demo-style', option.val);
					dt_demo._changeStyle(option, container, initStyle);
				},
				'<p><a href="https://datatables.net/tn/20#Styling-framework">What is this?</a></p>'
			);
		}

		// Theme selector options
		dt_demo._options(
			'Colour scheme',
			optionsContainer,
			[
				{
					icon: 'auto',
					label: 'Auto',
					val: 'auto'
				},
				{
					icon: 'light',
					label: 'Light',
					val: 'light'
				},
				{
					icon: 'dark',
					label: 'Dark',
					val: 'dark'
				}
			],
			dt_demo.storage.get('dt-demo-scheme') || 'auto',
			function (option, container, initChange) {
				dt_demo.storage.set('dt-demo-scheme', option.val);
				dt_demo._changeTheme(option.val, container, initChange);
			},
			'<p><a href="https://datatables.net/tn/20#Theme">What is this?</a></p>'
		);

		if (types && types.run) {
			types.run();
		}
	},

	_editorExamples: function () {
		Dom.s(document).on('initEditor', function (e, editor) {
			// Show and syntax highlight submit and return data
			editor.on('preSubmit', function (e, data) {
				dt_demo._highlightElement(
					'div.ajax-data-send code',
					decodeURI(
						DataTable.ajax
							.serialize(data)
							.replace(/&/g, '\n')
							.replace(/\+/g, ' ')
					)
				);
			});

			editor.on('postSubmit', function (e, json, data) {
				dt_demo._highlightElement(
					'div.ajax-data-receive code',
					JSON.stringify(json, null, 2)
				);
			});

			// Server-side script - replace the DataTables script display with
			// one customised for Editor. This is actually tab index 4 from the
			// DT tabs, but due to the reorder above it gets moved down one
			var server = Dom.s('div.dt-tabs > div').eq(3);

			//
			// Modify the tabs from the DataTables default examples to show the
			// extras information we want for Editor
			//

			// Ajax load data - rename and move to the end
			Dom.s('ul.dt-tabs li').eq(3).html('Ajax load').appendTo('ul.dt-tabs');
			Dom.s('div.dt-tabs > div').eq(3).appendTo('div.dt-tabs');

			// Ajax data interchange between Editor and the server
			Dom.s('ul.dt-tabs').append(Dom.c('li').text('Ajax data'));
			Dom.c('div')
				.classAdd('ajax-data')
				.html(
					'<p>Editor submits and retrieves information by Ajax requests. The two blocks below show the data that Editor submits and receives, to and from the server. This is updated live as you interact with Editor so you can see what is submitted.</p>' +
						'<div class="column_half ajax-data-send">' +
						'<h3>Submitted data:</h3>' +
						'<p>The following shows the data that has been submitted to the server when a request is made by Editor to add, edit or delete data from the table.</p>' +
						'<code class="multiline language-js">// No data yet submitted</code>' +
						'</div>' +
						'<div class="column_half ajax-data-receive">' +
						'<h3>Server response:</h3>' +
						'<p>The following shows the data that has been returned by the server in response to the data submitted on the left and is then acted upon.</p>' +
						'<code class="multiline language-js">// No data yet received</code>' +
						'</div>' +
						'<div class="clear"></div>'
				)
				.appendTo('div.dt-tabs');

			var ssFetched = false;

			Dom.s('#example').on('preXhr.dt', function () {
				if (ssFetched) {
					return;
				}

				var table = new DataTable.Api('#example');
				var url = table.ajax.url();

				if (url && url.indexOf('php') !== -1) {
					Dom.s('ul.dt-tabs li')
						.eq(3)
						.html('Server script')
						.css('display', 'block');

					server
						.find('p')
						.eq(0)
						.html(
							'The following script is used by DataTables and Editor to process the data requests sent by the client on the server-side.'
						);

					DataTable.ajax({
						url: '../resources/examples.php',
						data: {
							src: table.ajax.url()
						},
						dataType: 'text',
						type: 'post',
						success: function (txt) {
							Dom.s('div.dt-tabs > div.php').append(
								Dom
									.c('code')
									.classAdd('multiline language-php')
									.text(txt)
							);

							dt_demo._highlightElement('div.dt-tabs div.php code');
							ssFetched = true;
						}
					});
				}
			});

			// Expose so we can access it externally
			dt_demo.editor = editor;
		});
	},

	_functionHasBody: function (fn) {
		var str = fn.toString();
		var body = str.slice(str.indexOf('{') + 1, str.lastIndexOf('}'));

		return body.trim().length !== 0;
	},

	_optionsWarning: function (selector, msg) {
		// Remove message
		Dom
			.s(selector)
			.find('div.dt-demo-selector__current i.dt-demo-icon.warning')
			.remove();
		Dom
			.s(selector)
			.find('div.dt-demo-selector__options p.dt-demo-warning')
			.remove();

		if (msg === false) {
			return;
		}

		Dom
			.s(selector)
			.find('div.dt-demo-selector__current')
			.prepend(
				Dom
					.c('i')
					.classAdd('dt-demo-icon warning')
					.css('margin-right', '0.75em')
			);

		Dom
			.s(selector)
			.find('div.dt-demo-selector__title')
			.append(
				Dom
					.c('p')
					.classAdd('dt-demo-warning')
					.html('<i class="dt-demo-icon warning"></i> ' + msg)
			);
	},

	_options: function (title, container, options, initVal, cb, info) {
		var initChange = true;
		var selector = Dom
			.c('div')
			.classAdd('dt-demo-selector')
			.append(Dom.c('div').classAdd('dt-demo-selector__current'))
			.append(Dom.c('div').classAdd('dt-demo-selector__options'))
			.appendTo(container)
			.on('click', '.dt-demo-selector__option', function () {
				var val = Dom.s(this).data('val');
				var option = options.find(o => o.val == val);

				selector
					.find('div.dt-demo-selector__option')
					.classRemove('selected')
					.filter('[data-val="' + val + '"]')
					.classAdd('selected');

				cb(option, selector, initChange);

				// 'tis true for the first run, to let us know that it was
				// the first run
				initChange = false;
			});

		var currentEl = selector.find('.dt-demo-selector__current');
		var optionsEl = selector.find('.dt-demo-selector__options');

		// Add the options
		for (var i = 0; i < options.length; i++) {
			var option = options[i];
			var optionEl = Dom
				.c('div')
				.classAdd('dt-demo-selector__option')
				.attr('data-val', option.val)
				.append(Dom.c('span').text(option.label))
				.appendTo(optionsEl);

			if (option.icon) {
				Dom
					.c('i')
					.classAdd('dt-demo-icon')
					.classAdd(option.icon)
					.prependTo(optionEl);

				hasIcons = true;
			}
		}

		optionsEl.prepend(
			Dom
				.c('div')
				.classAdd('dt-demo-selector__title')
				.html(title + info)
		);

		// Show / hide dropdown
		currentEl.on('click', function () {
			if (optionsEl.css('display') === 'block') {
				optionsEl.css('display', 'none');

				Dom.s('body').off('click.dt-theme-selector');
			}
			else {
				optionsEl.css('display', 'block');

				setTimeout(function () {
					Dom.s('body').on('click.dt-theme-selector', function (e) {
						if (Dom.s(e.target).closest(optionsEl).filter(selector).count()) {
							return;
						}

						currentEl.trigger('click'); // hide
					});
				}, 10);
			}
		});

		// Trigger initial selection
		Dom
			.s(selector)
			.find('div.dt-demo-selector__option')
			.filter('[data-val="' + initVal + '"]')
			.trigger('click');

		return selector;
	},

	_changeStyle: function (option, selector, initChange) {
		if (!initChange) {
			// Reload - localStorage on next load will select the correct run code
			window.location.reload();
			return;
		}

		Dom.s(selector).find('div.dt-demo-selector__current').text(option.label);

		var target = dt_demo._struct.libs.targetFramework;
		var applied = option.val;

		if (target && target !== option.val) {
			var styleName = dt_demo._getPageStylingName(target);
			applied = target;

			dt_demo._optionsWarning(
				selector,
				'This example explicity uses ' +
					styleName +
					' and your selection has been disabled for this page.'
			);
		}

		dt_demo._setPageStyling(applied);
		dt_demo._tableClass(applied);

		dt_demo._appliedStyle = applied;
	},

	_changeTheme: function (val, selector) {
		if (val === 'auto') {
			var prefers = window.matchMedia('(prefers-color-scheme: dark)').matches
				? 'dark'
				: 'light';

			val = prefers == 'dark' ? 'dark' : 'light';
		}

		// Warnings if incompatible
		var styling = dt_demo._appliedStyle;
		var targetTheme = val;

		if (val === 'dark') {
			if (
				!styling ||
				styling === 'bootstrap5' ||
				styling === 'datatables' ||
				styling === 'bulma'
			) {
				dt_demo._optionsWarning(selector, false);
			}
			else {
				val = 'light';
				dt_demo._optionsWarning(
					selector,
					dt_demo._getPageStylingName(styling) +
						' does not have a dark theme mode. Light theme is shown.'
				);
			}
		}

		if (val === 'dark') {
			Dom
				.s('html')
				.classRemove('light') // DataTables
				.classAdd('dark')
				.attr('data-bs-theme', 'dark') // Bootstrap
				.attr('data-theme', 'dark'); // Bulma
			Dom
				.s('div.chart-display')
				.classRemove('highcharts-light')
				.classAdd('highcharts-dark');
		}
		else if (val === 'light') {
			Dom
				.s('html')
				.classRemove('dark') // DataTables
				.classAdd('light')
				.attr('data-bs-theme', 'light') // Bootstrap
				.attr('data-theme', 'light'); // Bulma
			Dom
				.s('div.chart-display')
				.classRemove('highcharts-dark')
				.classAdd('highcharts-light');
		}

		// Update the current element
		var current = Dom.s(selector).find('div.dt-demo-selector__current');

		if (!current.children('i.theme').count()) {
			current.append(Dom.c('i').classAdd('dt-demo-icon theme'));
		}

		current
			.find('i.theme')
			.classRemove('light dark auto')
			.classAdd(targetTheme);
	},

	_setPageStyling: function (styling) {
		var body = Dom.s('body');

		if (styling === 'bootstrap') {
			body.classAdd('dt-example-bootstrap');
		}
		else if (styling === 'bootstrap4') {
			body.classAdd('dt-example-bootstrap4');
		}
		else if (styling === 'bootstrap5') {
			body.classAdd('dt-example-bootstrap5');
		}
		else if (styling === 'foundation') {
			body.classAdd('dt-example-foundation');
		}
		else if (styling === 'jqueryui') {
			body.classAdd('dt-example-jqueryui');
		}
		else if (styling === 'semanticui') {
			body.classAdd('dt-example-semanticui');
		}
		else if (styling === 'bulma') {
			body.classAdd('dt-example-bulma');
		}
		else if (styling === 'material') {
			body.classAdd('dt-example-material');
		}
		else if (styling === 'uikit') {
			body.classAdd('dt-example-uikit');
		}
	},

	_getPageStylingName: function (styling) {
		if (styling === 'bootstrap') {
			return 'Bootstrap 3';
		}
		else if (styling === 'bootstrap4') {
			return 'Bootstrap 4';
		}
		else if (styling === 'bootstrap5') {
			return 'Bootstrap 5';
		}
		else if (styling === 'foundation') {
			return 'Foundation';
		}
		else if (styling === 'jqueryui') {
			return 'jQuery UI';
		}
		else if (styling === 'semanticui') {
			return 'Fomantic UI';
		}
		else if (styling === 'bulma') {
			return 'Bulma';
		}
		else if (styling === 'material') {
			return 'Material';
		}
		else if (styling === 'uikit') {
			return 'UI Kit';
		}

		return 'DataTables';
	},

	_getFileName: function (ext) {
		switch (ext) {
			case 'autofill':
				return 'autoFill';
			case 'cardview':
				return 'cardView';
			case 'colreorder':
				return 'colReorder';
			case 'columncontrol':
				return 'columnControl';
			case 'datatables':
				return 'dataTables';
			case 'datetime':
				return 'dateTime';
			case 'fixedcolumns':
				return 'fixedColumns';
			case 'fixedheader':
				return 'fixedHeader';
			case 'keytable':
				return 'keyTable';
			case 'rowgroup':
				return 'rowGroup';
			case 'rowreorder':
				return 'rowReorder';
			case 'searchbuilder':
				return 'searchBuilder';
			case 'searchpanes':
				return 'searchPanes';
			case 'staterestore':
				return 'stateRestore';
			default:
				return ext;
		}
	},

	_getFrameworkFile: function (fw) {
		switch (fw) {
			case 'datatables':
				return 'dataTables';
			default:
				return fw;
		}
	},

	_tableClass: function (fw) {
		var table = Dom.s('table');

		switch (fw) {
			case 'bootstrap':
			case 'bootstrap4':
				table.classAdd('table table-striped table-bordered table-hover');
				break;

			case 'bootstrap5':
				table.classAdd('table table-striped table-hover');
				break;

			case 'bulma':
				table.classAdd('table is-striped is-hoverable');
				break;

			case 'foundation':
				table.classAdd('hover');
				break;

			case 'material':
				table.classAdd('mdl-data-table');
				break;

			case 'semanticui':
				table.classAdd('ui selectable striped celled table');
				break;

			case 'uikit':
				table.classAdd('uk-table uk-table-hover uk-table-striped');
				break;

			default:
				break;
		}

		if (window.DataTable) {
			DataTable.tables({ visible: true, api: true }).columns.adjust();
		}
	},

	_displayFiles: function (sel, files) {
		var ul = Dom.s(sel);

		files.forEach(function (src) {
			ul.append(Dom.c('li').append(Dom.c('a').attr('href', src).html(src)));
		});
	}
};

}());
