Extract JavaScript from Perl code to separate file

This commit is contained in:
Nicolas Saillant 2024-07-04 11:45:04 +02:00
parent 46f4171ec0
commit b0f0f10bc1
3 changed files with 378 additions and 336 deletions

View File

@ -0,0 +1,254 @@
const $mainContainer = $('#main_container');
const $platformContainer = $('#platform_container');
const $packageContainer = $('#package_container');
let release = "";
let packages = [];
function getAllTestDirectories(data) {
return data.platforms.flatMap(platform => platform.test_directories.map(directory => directory.test_directory));
}
function clearPackagesOptions() {
$('#packagesSelector option').each(function() {
if ($(this).val() !== 'all' && !packages.includes($(this).val())) {
$(this).remove();
}
});
}
function filterByPlatform(platform) {
const $packageSelector = $('#packagesSelector');
$packageSelector.prop('disabled', platform !== 'all');
$platformContainer.find('.platform').each(function() {
const $this = $(this);
if (platform === 'all' || $this.hasClass(platform)) {
$this.show();
} else {
$this.hide();
}
});
}
function filterByPackage(package) {
const $platformSelector = $('#platformSelector');
const $packageContainers = $packageContainer.find('.package');
if (package === 'all') {
$platformSelector.prop('disabled', false);
$platformContainer.show();
$packageContainer.hide();
} else {
$platformSelector.prop('disabled', true);
$platformContainer.hide();
$packageContainer.show();
}
$packageContainers.each(function() {
const $this = $(this);
if (package === 'all' || $this.hasClass(package)) {
$this.show();
} else {
$this.hide();
}
});
}
function filterByLetter(letter) {
const $letterContainers = $mainContainer.find('.letter_container');
$letterContainers.each(function() {
const $this = $(this);
if (letter === 'all' || $this.hasClass(letter)) {
$this.show();
} else {
$this.hide();
}
if ($this.children().length <= 2) {
$this.hide();
}
});
}
function search() {
const searchTerm = $('#searchInput').val().toLowerCase();
const releaseType = $('#releaseSelector').val();
const $resultsContainer = $('#searchResults');
$resultsContainer.empty();
if (!searchTerm) {
$resultsContainer.append('<p>Please enter a search term.</p>');
return;
}
const matchingDirectories = [];
window.data.platforms.forEach(platform => {
platform.test_directories.forEach(directory => {
if (directory.content.toLowerCase().includes(searchTerm)) {
matchingDirectories.push({
test_directory: directory.test_directory,
platform_name: platform.name
});
}
});
});
if (matchingDirectories.length === 0) {
$resultsContainer.append('<p>No matching directories found.</p>');
} else {
matchingDirectories.forEach(match => {
const link = `${window.data.release}/${match.test_directory}/TestReport_${match.platform_name}.gz`;
$resultsContainer.append(`<p><a href="${link}" target="_blank">${match.platform_name} - ${match.test_directory} - <strong>${window.data.release}</strong></a></p>`);
});
}
}
function packageContainer(platforms) {
const testDirectories = {};
platforms.forEach(platform => {
platform.test_directories.forEach(testDir => {
if (!testDirectories[testDir.test_directory]) {
testDirectories[testDir.test_directory] = {};
}
if (!testDirectories[testDir.test_directory][testDir.letters]) {
testDirectories[testDir.test_directory][testDir.letters] = [];
}
testDirectories[testDir.test_directory][testDir.letters].push({
platformName: platform.name,
content: testDir.content
});
});
});
for (const [testDirectory, letters] of Object.entries(testDirectories)) {
const $container = $('<div>', { class: 'package ' + testDirectory }).appendTo($packageContainer);
$('<h2>').text(testDirectory).appendTo($container);
for (const [letter, platformDetails] of Object.entries(letters)) {
const $letterContainer = $('<div>', {
class: 'letter_container ' + letter,
}).appendTo($container);
$('<h3>').text(letter).appendTo($letterContainer);
platformDetails.forEach(detail => {
const { platformName, content } = detail;
const $platformContainer = $('<div>', { class: 'platform-container' }).appendTo($letterContainer);
const $platformLink = $('<a>', {
href: `${release}/${testDirectory}/TestReport_${platformName}.gz`,
text: platformName,
class: 'platform-link'
}).appendTo($platformContainer);
const $contentSpan = $('<pre>', {
text: content,
class: 'summary-content',
css: { display: 'none' }
}).appendTo($letterContainer);
if (content.length > 0) {
const $toggleButton = $('<button>', {
class: 'toggle-button',
text: 'Show More',
click: function() {
if ($contentSpan.is(':hidden')) {
$contentSpan.show().css('background-color', '#D0D0E0');
$(this).text('Show Less');
} else {
$contentSpan.hide().css('background-color', 'transparent');
$(this).text('Show More');
}
}
}).appendTo($platformContainer);
}
$('<br>').appendTo($letterContainer);
});
}
}
}
function platformContainer(platforms) {
platforms.forEach(platform => {
const $container = $('<div>', { class: 'platform ' + platform.name }).appendTo($platformContainer);
$container.html("<h2>Results of " + platform.name + "</h2>");
$('<p>', { class: 'tplinfo', html: platform.third_party_libraries }).appendTo($container);
const letters = ['n', 'w', 'o', 'r'];
letters.forEach(letter => {
const $letterContainer = $('<div>', { class: 'letter_container ' + letter }).appendTo($container);
$('<h3>').text(letter).appendTo($letterContainer);
const testDirectoriesForLetter = platform.test_directories.filter(directory => directory.letters === letter);
testDirectoriesForLetter.forEach(directory => {
const $directoryContainer = $('<div>', { class: 'directory_container' }).appendTo($letterContainer);
const $directoryName = $('<a>', {
href: `${release}/${directory.test_directory}/TestReport_${platform.name}.gz`,
text: `${directory.test_directory} `
}).appendTo($directoryContainer);
const $contentSpan = $('<pre>', {
text: directory.content,
class: 'summary-content',
css: { display: 'none' }
}).appendTo($letterContainer);
if (directory.content.length > 0) {
const $toggleButton = $('<button>', {
class: 'toggle-button',
text: 'Show More',
click: function() {
if ($contentSpan.is(':hidden')) {
$contentSpan.show().css('background-color', '#D0D0E0');
$(this).text('Show Less');
} else {
$contentSpan.hide().css('background-color', 'transparent');
$(this).text('Show More');
}
}
}).appendTo($directoryContainer);
$('<br>').appendTo($letterContainer);
}
});
if ($letterContainer.children().length <= 2) {
$letterContainer.hide();
}
});
});
}
function openAll() {
$('.summary-content').show().css('background-color', '#D0D0E0');
$('.toggle-button').text('Show Less');
}
function closeAll() {
$('.summary-content').hide().css('background-color', 'transparent');
$('.toggle-button').text('Show More');
}
function main() {
const url = searchURLs["current"];
$.getJSON(url, data => {
window.data = data;
release = data.release;
packages = getAllTestDirectories(data);
clearPackagesOptions();
platformContainer(data.platforms);
packageContainer(data.platforms);
$packageContainer.hide();
const urlParams = new URLSearchParams(window.location.search);
const platform = urlParams.get('platform');
if (platform) {
console.log("Platform is " + platform);
filterByPlatform(platform);
}
const package = urlParams.get('package');
if (package) {
console.log("Package is " + package);
filterByPackage(package);
}
$('#open-all').click(openAll);
$('#close-all').click(closeAll);
$('#search-button').click(search);
}).fail(error => console.log(error));
}
$(document).ready(main);

View File

@ -464,22 +464,22 @@ sub print_platform_descriptions()
<h2><a name="platforms">Platform Description and Summary</a></h2>
<table border="1" cellspacing="2" cellpadding="5" class="summary">
<tr align="center">
<th colspan="2">OS and compiler</th>
<th>Tester</th>
<th class="ok">y</th>
<th class="third_party_warning">t</th>
<th class="warning">w</th>
<th class="timeout">o</th>
<th class="error">n</th>
<th class="requirements">r</th>
<th>CMake</th>
<th>BOOST</th>
<th>MPFR</th>
<th>GMP</th>
<th>QT</th>
<th>LEDA</th>
<th>CXXFLAGS</th>
<th>LDFLAGS</th>
<th colspan="2">OS and compiler</th>
<th>Tester</th>
<th class="ok">y</th>
<th class="third_party_warning">t</th>
<th class="warning">w</th>
<th class="timeout">o</th>
<th class="error">n</th>
<th class="requirements">r</th>
<th>CMake</th>
<th>BOOST</th>
<th>MPFR</th>
<th>GMP</th>
<th>QT</th>
<th>LEDA</th>
<th>CXXFLAGS</th>
<th>LDFLAGS</th>
</tr>
EOF
my ($platform_num)=(0);
@ -613,35 +613,32 @@ sub print_little_header(){
"https://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>${release_name} Test Results</title>
<link rel="shortcut icon" href="cgal.ico">
<link rel="stylesheet" type="text/css" href="testresult.css">
<!-- This file is generated by a program. Do not edit manually!! -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>${release_name} Test Results</title>
<link rel="shortcut icon" href="cgal.ico">
<link rel="stylesheet" type="text/css" href="testresult.css">
<!-- This file is generated by a program. Do not edit manually!! -->
</head>
<body>
<h1>Test Results of ${release_name}
<a id="permalink" href="results-${release_version}.shtml">permalink</a>
<a id="jump_to_results" href="#testresults">jump to results</a>
<a id="compare" href="comparison/diff_testsuites.html?newTest=${release_name}">compare results...</a></h1>
<!--#include virtual="versions.inc"-->
<p>The results of the tests are presented in a table
('y' = success, 'w' = warning, 't' = third party warning, 'o' = timeout, 'n' = failure, 'r' = a requirement is not found),
and the error + compiler output from each test can be retrieved by clicking
on it.</p>
<p><b>N.B. The detection of warnings is not exact.
Look at the output to be sure!</b></p>
<ol>
<li><a href="${releases_url}">
Downloading internal releases</a></li>
<li><a href="${doxygen_manual_test_url}${release_name}/" style="color: red">
The doxygen documentation testpage</a>
(and the <a href="${doxygen_manual_test_url}">overview page</a>)</li>
<li><a href="https://cgal.geometryfactory.com/~cgaltest/testsuite_comparison/diff_testsuites.html">
Diff of testsuites results</a></li>
<li><a href="summary-$release_version.html">
Summary Page</a></li>
</ol>
<h1>Test Results of ${release_name}
<a id="permalink" href="results-${release_version}.shtml">permalink</a>
<a id="jump_to_results" href="#testresults">jump to results</a>
<a id="compare" href="comparison/diff_testsuites.html?newTest=${release_name}">compare results...</a></h1>
<!--#include virtual="versions.inc"-->
<p>The results of the tests are presented in a table
('y' = success, 'w' = warning, 't' = third party warning, 'o' = timeout, 'n' = failure, 'r' = a requirement is not found),
and the error + compiler output from each test can be retrieved by clicking
on it.</p>
<p><b>N.B. The detection of warnings is not exact.
Look at the output to be sure!</b></p>
<ol>
<li><a href="${releases_url}">Downloading internal releases</a></li>
<li><a href="${doxygen_manual_test_url}${release_name}/" style="color: red">The doxygen documentation testpage</a>
(and the <a href="${doxygen_manual_test_url}">overview page</a>)</li>
<li><a href="https://cgal.geometryfactory.com/~cgaltest/testsuite_comparison/diff_testsuites.html">Diff of testsuites results</a></li>
<li><a href="summary-$release_version.html">
Summary Page</a></li>
</ol>
EOF
}
@ -751,12 +748,12 @@ sub create_summary_page {
my $test_directory;
my @letters = ('r', 'n', 'w', 'o');
my $letters_options = join("\n", map { "<option value=\"$_\">$_</option>" } @letters);
my $package_options = join("\n", map { "<option style=\"display: none;\" value=\"$_\">$_</option>" } sort keys %test_directories);
my $third_party_libraries = "";
my $package_options = join("\n", map { "<option value=\"$_\">$_</option>" } sort keys %test_directories);
my @search_index;
my @platforms_data;
my ($platform_num, $platform) = (0, "");
foreach $platform (@platforms_to_do) {
my $third_party_libraries = "";
if (open (PLATFORM_INFO, "results_${platform}.info")) {
my $line = "";
while (<PLATFORM_INFO>) {
@ -764,31 +761,37 @@ sub create_summary_page {
if ($line =~ /^TPL:/) {
$third_party_libraries = $line;
}
print "$line\n";
}
close PLATFORM_INFO;
}
my $platform_info = {
name => $platform,
third_party_libraries => $third_party_libraries,
test_directories => [],
};
foreach my $letter (@letters) {
foreach my $test_directory (sort keys %test_directories) {
my $resulttext = $testresults[$platform_num]->{$test_directory};
if (defined($resulttext) && $resulttext eq $letter) {
my $warnings_and_errors = get_warnings_and_errors("$testresult_dir/$release_name/$test_directory/TestReport_$platform.gz");
push @search_index, {
platform => $platform,
push @{$platform_info->{test_directories}}, {
test_directory => $test_directory,
content => $warnings_and_errors,
release => $release_name,
letters => $letter,
third_party_libraries => $third_party_libraries,
};
}
}
}
push @platforms_data, $platform_info;
$platform_num++;
}
my $final_data = {
release => $release_name,
platforms => \@platforms_data,
};
my $json = JSON->new->allow_nonref;
my $json_text = $json->pretty->encode(\@search_index);
my $json_text = $json->pretty->encode($final_data);
open my $fh, '>', "$testresult_dir/$release_name/search_index.json" or die "Could not open file: $!";
print $fh $json_text;
close $fh;
@ -803,289 +806,48 @@ sub create_summary_page {
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"https://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Summary</title>
<link rel="shortcut icon" href="cgal.ico">
<link rel="stylesheet" type="text/css" href="testresult.css">
<script>
var searchURLs = $json_urls;
var url = searchURLs["current"]
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('platformSelector').addEventListener('change', function() {
filterByPlatform();
filterByLetter();
});
document.getElementById('letterSelector').addEventListener('change', function() {
filterByLetter();
});
document.getElementById('packagesSelector').addEventListener('change', function() {
filterByPackage();
filterByLetter();
});
var platformSelector = document.getElementById('platformSelector');
const platformQueryString = window.location.search;
const platformUrlParams = new URLSearchParams(platformQueryString);
const platform = platformUrlParams.get('platform');
for (let option of platformSelector.options) {
if (option.value === platform) {
platformSelector.value = platform;
break;
}
}
var letterSelector = document.getElementById('letterSelector');
var packagesSelector = document.getElementById('packagesSelector');
const packageQueryString = window.location.search;
const packageUrlParams = new URLSearchParams(packageQueryString);
const package = packageUrlParams.get('package');
for (let option of packagesSelector.options) {
if (option.value === package) {
packagesSelector.value = package;
document.getElementById('container').style.display = 'none';
break;
}
}
fetch(url)
.then(response => response.json())
.then(data => {
const groupedByPlatform = data.reduce((acc, item) => {
if (!acc[item.platform]) {
acc[item.platform] = [];
}
acc[item.platform].push(item);
return acc;
}, {});
const container = document.getElementById('container');
Object.entries(groupedByPlatform).forEach(([platform, items]) => {
const platformDiv = document.createElement('div');
platformDiv.className = "platform " + platform;
container.appendChild(platformDiv);
const platformHeader = document.createElement('h2');
platformHeader.innerText = "Results of " + platform;
platformDiv.appendChild(platformHeader);
const tplDiv = document.createElement('div');
tplDiv.innerHTML = items[0].third_party_libraries;
platformDiv.appendChild(tplDiv);
const resultGrid = document.createElement('div');
resultGrid.className = "result-grid";
platformDiv.appendChild(resultGrid);
const letters = ['r', 'n', 'w', 'o'];
letters.forEach(letter => {
const letterDiv = document.createElement('div');
letterDiv.className = "letter " + letter + " result-container";
resultGrid.appendChild(letterDiv);
const letterHeader = document.createElement('h3');
letterHeader.innerText = letter;
letterDiv.appendChild(letterHeader);
const filteredItems = items.filter(item => item.letters === letter);
filteredItems.forEach(item => {
const resultDiv = document.createElement('div');
resultDiv.innerHTML = `<a href="\${item.release}/\${item.test_directory}/TestReport_\${item.platform}.gz">\${item.test_directory}</a>`;
letterDiv.appendChild(resultDiv);
if (item.content) {
const pre = document.createElement('pre');
pre.innerText = item.content;
letterDiv.appendChild(pre);
}
});
});
});
const testDirectories = [...new Set(data.map(item => item.test_directory))];
for (let option of packagesSelector.options) {
if (testDirectories.includes(option.value)) {
option.style.display = '';
}
}
const groupedByPackage = data.reduce((acc, item) => {
if (!acc[item.test_directory]) {
acc[item.test_directory] = [];
}
acc[item.test_directory].push(item);
return acc;
}
, {});
const packageContainer = document.getElementById('package_container');
Object.entries(groupedByPackage).forEach(([test_directory, items]) => {
const packageDiv = document.createElement('div');
packageDiv.className = "package";
packageContainer.appendChild(packageDiv);
const packageHeader = document.createElement('h2');
packageHeader.innerText = test_directory;
packageDiv.appendChild(packageHeader);
const resultGrid = document.createElement('div');
resultGrid.className = "result-grid";
packageDiv.appendChild(resultGrid);
const letters = ['r', 'n', 'w', 'o'];
letters.forEach(letter => {
const letterDiv = document.createElement('div');
letterDiv.className = "letter " + letter + " result-container";
resultGrid.appendChild(letterDiv);
const letterHeader = document.createElement('h3');
letterHeader.innerText = letter;
letterDiv.appendChild(letterHeader);
const filteredItems = items.filter(item => item.letters === letter);
filteredItems.forEach(item => {
const resultDiv = document.createElement('div');
resultDiv.innerHTML = `<a href="\${item.release}/\${item.test_directory}/TestReport_\${item.platform}.gz">\${item.platform}</a>`;
letterDiv.appendChild(resultDiv);
if (item.content) {
const pre = document.createElement('pre');
pre.innerText = item.content;
letterDiv.appendChild(pre);
}
});
});
});
})
.then(() => {
filterByPackage();
filterByPlatform();
filterByLetter();
})
.catch(error => console.error('Error loading search data:', error));
});
function filterByPlatform() {
var selectedPlatform = document.getElementById('platformSelector').value;
var selectedLetter = document.getElementById('letterSelector').value;
var platforms = document.querySelectorAll('div.platform');
var packageSelector = document.getElementById('packagesSelector');
if (selectedPlatform !== 'all') {
packageSelector.disabled = true;
packageSelector.value = 'all';
} else {
packageSelector.disabled = false;
}
platforms.forEach(function(platform) {
var displayPlatform = false;
if (selectedPlatform === 'all' || platform.classList.contains(selectedPlatform)) {
var letters = platform.querySelectorAll('div.letter');
letters.forEach(function(letter) {
if (selectedLetter === 'all' || letter.classList.contains(selectedLetter)){
letter.style.display = '';
displayPlatform = true;
} else {
letter.style.display = 'none';
}
});
platform.style.display = displayPlatform ? '' : 'none';
} else {
platform.style.display = 'none';
}
});
}
function filterByLetter() {
var selectedLetter = document.getElementById('letterSelector').value;
var letters = document.querySelectorAll('div.letter');
letters.forEach(function(letter) {
if (selectedLetter === 'all' || letter.classList.contains(selectedLetter)) {
if (letter.children.length > 1){
letter.style.display = '';
} else {
letter.style.display = 'none';
}
} else {
letter.style.display = 'none';
}
});
}
function filterByPackage() {
var selectedPackage = document.getElementById('packagesSelector').value;
var container = document.getElementById('container');
var package_container = document.getElementById('package_container');
let children = container.children;
if (selectedPackage === 'all') {
platformSelector.disabled = false;
for (let i = 0; i < children.length; i++) {
children[i].style.display = '';
}
package_container.style.display = 'none';
container.style.display = '';
} else {
platformSelector.disabled = true;
platformSelector.value = 'all';
for (let i = 0; i < children.length; i++) {
children[i].style.display = 'none';
}
package_container.style.display = '';
for (let i=0; i<package_container.children.length; i++) {
let packageDiv = package_container.children[i];
if (packageDiv.querySelector('h2').innerText === selectedPackage) {
packageDiv.style.display = '';
} else {
packageDiv.style.display = 'none';
}
}
}
}
function search() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
const selectValue = document.getElementById('releaseSelector').value;
if (searchTerm === '') {
return;
}
const urls = searchURLs[selectValue];
if (!urls) {
console.error('No URLs found for select value:', selectValue);
return;
}
urls.forEach(url => {
fetch(url)
.then(response => response.text())
.then(data => {
const searchIndex = JSON.parse(data);
const searchResults = searchIndex.filter(item => item.content.toLowerCase().includes(searchTerm));
const searchResultsDiv = document.getElementById('searchResults');
if (url === urls[0]) searchResultsDiv.innerHTML = '';
searchResults.forEach(item => {
const resultDiv = document.createElement('div');
resultDiv.innerHTML = `<a href="\${item.release}/\${item.test_directory}/TestReport_\${item.platform}.gz">\${item.platform} - \${item.test_directory} - <strong>\${item.release}</strong></a>`;
searchResultsDiv.appendChild(resultDiv);
});
})
.catch(error => console.error('Error loading search data:', error));
});
}
</script>
<!-- This file is generated by a program. Do not edit manually!! -->
</head>
<body>
<input type="text" id="searchInput" placeholder="Search ..." autocomplete="off" onkeypress="if(event.keyCode==13) search()">
<select id="releaseSelector">
<option value="current" selected>This release</option>
<option value="all">All releases</option>
</select>
<button onclick="search()">Search</button>
<div id="searchResults"></div>
<h1>Summary Results of ${release_name}</h1>
<select id="platformSelector" onchange="filterByPlatform()">
<option value="all" selected>Select a platform</option>
$platform_options
</select>
<select id="letterSelector" onchange="filterByLetter()">
<option value="all" selected>All</option>
$letters_options
</select>
<select id="packagesSelector" onchange="filterByPackage()">
<option value="all" selected>Select a package</option>
$package_options
</select>
<div id="container"></div>
<div id="package_container"></div>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Summary</title>
<link rel="shortcut icon" href="cgal.ico">
<link rel="stylesheet" type="text/css" href="testresult.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
var searchURLs = $json_urls;
</script>
<!-- This file is generated by a program. Do not edit manually!! -->
</head>
<body>
<input type="text" id="searchInput" placeholder="Search ..." autocomplete="off" onkeypress="if(event.keyCode==13) search()">
<select id="releaseSelector">
<option value="current" selected>This release</option>
<option value="all">All releases</option>
</select>
<button onclick="search()">Search</button>
<div id="searchResults"></div>
<h1>Summary Results of ${release_name}</h1>
<select id="platformSelector" onchange="filterByPlatform(this.value)">
<option value="all" selected>Select a platform</option>
$platform_options
</select>
<select id="letterSelector" onchange="filterByLetter(this.value)">
<option value="all" selected>All</option>
$letters_options
</select>
<select id="packagesSelector" onchange="filterByPackage(this.value)">
<option value="all" selected>Select a package</option>
$package_options
</select>
<br>
<div>
<button id="open-all">Open All</button>
<button id="close-all">Close All</button>
</div>
<div id="main_container">
<div id="platform_container"></div>
<div id="package_container"></div>
</div>
<script src="Summary_Script.js"></script>
EOF
my $summary_page_path = "$testresult_dir/summary".substr($release_name,4).".html";

View File

@ -89,4 +89,30 @@ TABLE.result TD > a.package_name {
grid-template-columns: repeat(4, 1fr);
gap: 20px;
padding: 20px;
}
}
.toggle-button {
text-decoration: underline;
border: none;
color: #0000EE;
cursor: pointer;
}
.summary-content{
overflow: auto;
max-height: 600px;
}
.directory_container{
display: flex;
align-items: center;
}
.platform-container {
display: flex;
align-items: center;
}
.platform-link {
margin-right: 10px;
}