2022-08-30 14:10:01 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Available template block that can be overriden using $this->assign('table-overview', ' ');
|
|
|
|
* - `prepend-html`
|
|
|
|
* - `table-overview`
|
|
|
|
* - `detailed-summary-full`
|
|
|
|
* - `detailed-summary-mitre-attack`
|
|
|
|
* - `detailed-summary-type`
|
|
|
|
* - `detailed-summary-tags`
|
|
|
|
* - `detailed-summary-events`
|
|
|
|
* - `aggregated-context`
|
2022-09-07 10:35:51 +02:00
|
|
|
*
|
|
|
|
* Additional variables:
|
|
|
|
* - `event-table-include-basescore`: bool
|
2022-08-30 14:10:01 +02:00
|
|
|
*/
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
if (empty($this->__vars)) {
|
|
|
|
$this->__vars = [];
|
|
|
|
}
|
2022-09-07 10:35:51 +02:00
|
|
|
$default_vars = [
|
|
|
|
'event_table_include_basescore' => true,
|
2022-09-08 10:59:47 +02:00
|
|
|
'additional_taxonomy_event_list' => [
|
|
|
|
'PAP' => 'PAP:'
|
|
|
|
],
|
2022-09-07 10:35:51 +02:00
|
|
|
];
|
|
|
|
$vars = array_merge($default_vars, $this->__vars);
|
|
|
|
|
2022-08-30 14:10:01 +02:00
|
|
|
$event_number = count($events);
|
|
|
|
$attribute_number = 0;
|
|
|
|
$object_number = 0;
|
|
|
|
$event_report_number = 0;
|
|
|
|
$proposal_number = 0;
|
|
|
|
|
|
|
|
$attribute_types = [];
|
|
|
|
$object_types = [];
|
|
|
|
$all_event_report = [];
|
|
|
|
|
|
|
|
$all_tag_amount = [];
|
|
|
|
$unique_tag_number = 0;
|
|
|
|
$tag_color_mapping = [];
|
|
|
|
|
|
|
|
$mitre_attack_techniques = [];
|
|
|
|
$mitre_galaxy_tag_prefix = 'misp-galaxy:mitre-attack-pattern="';
|
|
|
|
|
|
|
|
foreach ($events as $event) {
|
2022-09-08 14:10:24 +02:00
|
|
|
$unique_tag_per_event = [];
|
2022-08-30 14:10:01 +02:00
|
|
|
$attribute_number += count($event['Attribute']);
|
|
|
|
$object_number += count($event['Object']);
|
|
|
|
$event_report_number += count($event['EventReport']);
|
|
|
|
$proposal_number += count($event['ShadowAttribute']);
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($event['EventTag'] as $event_tag) {
|
|
|
|
$tag = $event_tag['Tag'];
|
2022-09-08 14:10:24 +02:00
|
|
|
|
|
|
|
if (!empty($unique_tag_per_event[$tag['name']])) {
|
|
|
|
continue; // Only one instance of tag per event
|
|
|
|
}
|
|
|
|
$unique_tag_per_event[$tag['name']] = true;
|
|
|
|
|
2022-08-30 14:10:01 +02:00
|
|
|
if (empty($all_tag_amount[$tag['name']])) {
|
|
|
|
$all_tag_amount[$tag['name']] = 0;
|
|
|
|
$tag_color_mapping[$tag['name']] = $tag['colour'];
|
|
|
|
}
|
|
|
|
$all_tag_amount[$tag['name']] += 1;
|
|
|
|
|
|
|
|
if (!empty($tag['is_galaxy']) && substr($tag['name'], 0, strlen($mitre_galaxy_tag_prefix)) === $mitre_galaxy_tag_prefix) {
|
|
|
|
$technique = substr($tag['name'], strlen($mitre_galaxy_tag_prefix), strlen($tag['name']) - strlen($mitre_galaxy_tag_prefix) - 1);
|
|
|
|
$mitre_attack_techniques[$technique] = $event_tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($event['Attribute'] as $attribute) {
|
|
|
|
if (empty($attribute_types[$attribute['type']])) {
|
|
|
|
$attribute_types[$attribute['type']] = 0;
|
|
|
|
}
|
|
|
|
$attribute_types[$attribute['type']] += 1;
|
|
|
|
|
|
|
|
foreach ($attribute['AttributeTag'] as $attribute_tag) {
|
|
|
|
$tag = $attribute_tag['Tag'];
|
2022-09-08 14:10:24 +02:00
|
|
|
|
|
|
|
if (!empty($unique_tag_per_event[$tag['name']])) {
|
|
|
|
continue; // Only one instance of tag per event
|
|
|
|
}
|
|
|
|
$unique_tag_per_event[$tag['name']] = true;
|
|
|
|
|
2022-08-30 14:10:01 +02:00
|
|
|
if (empty($all_tag_amount[$tag['name']])) {
|
|
|
|
$all_tag_amount[$tag['name']] = 0;
|
|
|
|
$tag_color_mapping[$tag['name']] = $tag['colour'];
|
|
|
|
}
|
|
|
|
$all_tag_amount[$tag['name']] += 1;
|
|
|
|
|
|
|
|
if (!empty($tag['is_galaxy']) && substr($tag['name'], 0, strlen($mitre_galaxy_tag_prefix)) === $mitre_galaxy_tag_prefix) {
|
|
|
|
$technique = substr($tag['name'], strlen($mitre_galaxy_tag_prefix), strlen($tag['name']) - strlen($mitre_galaxy_tag_prefix) - 1);
|
|
|
|
$mitre_attack_techniques[$technique] = $attribute_tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($event['Object'] as $object) {
|
|
|
|
if (empty($object_types[$object['name']])) {
|
|
|
|
$object_types[$object['name']] = 0;
|
|
|
|
}
|
|
|
|
$object_types[$object['name']] += 1;
|
|
|
|
|
|
|
|
$attribute_number += count($object['Attribute']);
|
|
|
|
foreach ($object['Attribute'] as $attribute) {
|
|
|
|
if (empty($attribute_types[$attribute['type']])) {
|
|
|
|
$attribute_types[$attribute['type']] = 0;
|
|
|
|
}
|
|
|
|
$attribute_types[$attribute['type']] += 1;
|
|
|
|
|
|
|
|
foreach ($attribute['AttributeTag'] as $attribute_tag) {
|
|
|
|
$tag = $attribute_tag['Tag'];
|
2022-09-08 14:10:24 +02:00
|
|
|
|
|
|
|
if (!empty($unique_tag_per_event[$tag['name']])) {
|
|
|
|
continue; // Only one instance of tag per event
|
|
|
|
}
|
|
|
|
$unique_tag_per_event[$tag['name']] = true;
|
|
|
|
|
2022-08-30 14:10:01 +02:00
|
|
|
if (empty($all_tag_amount[$tag['name']])) {
|
|
|
|
$all_tag_amount[$tag['name']] = 0;
|
|
|
|
$tag_color_mapping[$tag['name']] = $tag['colour'];
|
|
|
|
}
|
|
|
|
$all_tag_amount[$tag['name']] += 1;
|
|
|
|
|
|
|
|
if (!empty($tag['is_galaxy']) && substr($tag['name'], 0, strlen($mitre_galaxy_tag_prefix)) === $mitre_galaxy_tag_prefix) {
|
|
|
|
$technique = substr($tag['name'], strlen($mitre_galaxy_tag_prefix), strlen($tag['name']) - strlen($mitre_galaxy_tag_prefix) - 1);
|
|
|
|
$mitre_attack_techniques[$technique] = $attribute_tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($event['EventReport'] as $event_report) {
|
|
|
|
$all_event_report[] = [
|
|
|
|
'uuid' => $event_report['uuid'],
|
|
|
|
'name' => $event_report['name'],
|
|
|
|
'event_id' => $event_report['event_id'],
|
|
|
|
'event_info' => $event['Event']['info'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-31 11:51:36 +02:00
|
|
|
if (!function_exists('findAndBuildTag')) {
|
2022-09-08 10:59:47 +02:00
|
|
|
function findAndBuildTag($tag_list, $tag_prefix, $that)
|
|
|
|
{
|
2022-08-31 11:51:36 +02:00
|
|
|
foreach ($tag_list as $tag) {
|
|
|
|
if (substr($tag['Tag']['name'], 0, strlen($tag_prefix)) == $tag_prefix) {
|
|
|
|
return $that->element('tag', ['tag' => $tag]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-30 14:10:01 +02:00
|
|
|
$unique_tag_number = count(array_keys($all_tag_amount));
|
|
|
|
|
|
|
|
arsort($attribute_types);
|
|
|
|
arsort($object_types);
|
|
|
|
arsort($all_tag_amount);
|
2022-08-31 11:51:36 +02:00
|
|
|
|
|
|
|
array_splice($attribute_types, 10);
|
|
|
|
array_splice($object_types, 10);
|
|
|
|
array_splice($all_tag_amount, 10);
|
2022-08-30 14:10:01 +02:00
|
|
|
?>
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<h1><?= !empty($filters['published']) ? __('Summary of published Events') : __('Summary of Events') ?></h1>
|
|
|
|
<?php if ($this->fetch('prepend-html')) : ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?= $this->fetch('prepend-html') ?>
|
|
|
|
<?php endif; ?>
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('table-overview')) : ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?= $this->fetch('table-overview'); ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php else : ?>
|
|
|
|
<div class="panel">
|
|
|
|
<h2><?= __('Data at a glance') ?></h2>
|
|
|
|
<table class="table table-condensed mw-50">
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Summary period') ?></td>
|
|
|
|
<td><?= h($period) ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Generation date') ?></td>
|
|
|
|
<td><?= date("c"); ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Events #') ?></td>
|
|
|
|
<td><?= $event_number ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Attributes #') ?></td>
|
|
|
|
<td><?= $attribute_number ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Objects #') ?></td>
|
|
|
|
<td><?= $object_number ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Event Report #') ?></td>
|
|
|
|
<td><?= $event_report_number ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Proposals #') ?></td>
|
|
|
|
<td><?= $proposal_number ?></td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td><?= __('Unique tags #') ?></td>
|
|
|
|
<td><?= $unique_tag_number ?></td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?php endif; ?>
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('detailed-summary-full')) : ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?= $this->fetch('detailed-summary-full'); ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php else : ?>
|
|
|
|
<div class="panel">
|
|
|
|
<h2><?= __('Detailed summary') ?></h2>
|
|
|
|
<?php if ($this->fetch('detailed-summary-mitre-attack')) : ?>
|
|
|
|
<?= $this->fetch('detailed-summary-mitre-attack'); ?>
|
|
|
|
<?php else : ?>
|
|
|
|
<?php if (!empty($mitre_attack_techniques)) : ?>
|
|
|
|
<h4><?= __('Mitre Att&ck techniques') ?></h4>
|
|
|
|
<ul>
|
|
|
|
<?php foreach ($mitre_attack_techniques as $technique => $tag) : ?>
|
|
|
|
<li>
|
|
|
|
<?php
|
2022-08-31 11:51:36 +02:00
|
|
|
$tag['Tag']['name'] = $technique;
|
|
|
|
echo $this->element('tag', ['tag' => $tag])
|
2022-09-08 10:59:47 +02:00
|
|
|
?>
|
|
|
|
</li>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
<?php endif; ?>
|
2022-08-31 11:51:36 +02:00
|
|
|
<?php endif; ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('detailed-summary-type')) : ?>
|
|
|
|
<?= $this->fetch('detailed-summary-type'); ?>
|
|
|
|
<?php else : ?>
|
|
|
|
<?php if (!empty($attribute_types)) : ?>
|
|
|
|
<h4><?= __('Top 10 Attribute types') ?></h4>
|
|
|
|
<ul>
|
|
|
|
<?php foreach ($attribute_types as $type => $amount) : ?>
|
|
|
|
<li><strong><?= h($type) ?></strong>: <?= $amount ?></li>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
<?php if (!empty($object_types)) : ?>
|
|
|
|
<h4><?= __('Top 10 MISP Object names') ?></h4>
|
|
|
|
<ul>
|
|
|
|
<?php foreach ($object_types as $name => $amount) : ?>
|
|
|
|
<li><strong><?= h($name) ?></strong>: <?= $amount ?></li>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
<?php if (!empty($all_event_report)) : ?>
|
|
|
|
<h4><?= __('All Event Reports') ?></h4>
|
|
|
|
<ul>
|
|
|
|
<?php foreach ($all_event_report as $report) : ?>
|
|
|
|
<li>
|
|
|
|
<a href="<?= sprintf('%s/eventReports/view/%s', $baseurl, h($report['uuid'])) ?>">
|
|
|
|
<?= sprintf('%s :: %s', h($report['event_info']), h($report['name'])); ?>
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
<?php endif; ?>
|
2022-08-31 11:51:36 +02:00
|
|
|
<?php endif; ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('detailed-summary-tags')) : ?>
|
|
|
|
<?= $this->fetch('detailed-summary-tags'); ?>
|
|
|
|
<?php else : ?>
|
|
|
|
<h4><?= __('Top 10 Tags') ?></h4>
|
2022-08-31 11:51:36 +02:00
|
|
|
<ul>
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php foreach ($all_tag_amount as $tag_name => $amount) : ?>
|
|
|
|
<li>
|
|
|
|
<?= $this->element('tag', ['tag' => ['Tag' => ['name' => $tag_name, 'colour' => $tag_color_mapping[$tag_name]]]]) ?>
|
2022-09-08 13:33:08 +02:00
|
|
|
<span style="padding: 2px 9px; border-radius: 9px; font-weight: bold; background-color: #999; color: #fff;">
|
|
|
|
<?= $amount ?>
|
|
|
|
</span>
|
2022-09-08 10:59:47 +02:00
|
|
|
</li>
|
2022-08-31 11:51:36 +02:00
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
<?php endif; ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('detailed-summary-events')) : ?>
|
|
|
|
<?= $this->fetch('detailed-summary-events'); ?>
|
|
|
|
<?php else : ?>
|
|
|
|
<?php if (!empty($events)) : ?>
|
|
|
|
<h3><?= __('Event list') ?></h3>
|
|
|
|
<table class="table table-condensed">
|
|
|
|
<thead>
|
2022-08-31 14:45:53 +02:00
|
|
|
<tr>
|
2022-09-08 10:59:47 +02:00
|
|
|
<th>Creator Org.</th>
|
|
|
|
<th>TLP</th>
|
|
|
|
<th><?= __('State') ?></th>
|
|
|
|
<th><?= __('Threat Level') ?></th>
|
|
|
|
<?php foreach ($vars['additional_taxonomy_event_list'] as $taxonomy_name => $taxonomy_prefix) : ?>
|
|
|
|
<th><?= h($taxonomy_name) ?></th>
|
2022-08-31 14:45:53 +02:00
|
|
|
<?php endforeach; ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if (!empty($vars['event_table_include_basescore'])) : ?>
|
|
|
|
<th><?= __('Decaying Base Score') ?></th>
|
2022-09-07 10:35:51 +02:00
|
|
|
<?php endif; ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
<th><?= __('Event Info') ?></th>
|
2022-08-31 14:45:53 +02:00
|
|
|
</tr>
|
2022-09-08 10:59:47 +02:00
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<?php foreach ($events as $event) : ?>
|
|
|
|
<?php
|
|
|
|
$workflowTag = findAndBuildTag($event['EventTag'], 'workflow:', $this);
|
|
|
|
$analysisHtml = !empty($workflowTag) ? $workflowTag : h($analysisLevels[$event['Event']['analysis']]);
|
|
|
|
$tlpTag = findAndBuildTag($event['EventTag'], 'tlp:', $this);
|
|
|
|
$tlpHtml = !empty($tlpTag) ? $tlpTag : h($distributionLevels[$event['Event']['distribution']]);
|
|
|
|
?>
|
|
|
|
<tr>
|
|
|
|
<td><?= h($event['Orgc']['name']) ?></td>
|
|
|
|
<td><?= $tlpHtml ?></td>
|
|
|
|
<td><?= $analysisHtml ?></td>
|
|
|
|
<td><?= h($event['ThreatLevel']['name']); ?></td>
|
|
|
|
<?php foreach ($vars['additional_taxonomy_event_list'] as $taxonomy_name => $taxonomy_prefix) : ?>
|
|
|
|
<td><?= findAndBuildTag($event['EventTag'], $taxonomy_prefix, $this) ?></td>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
<?php if (!empty($vars['event_table_include_basescore'])) : ?>
|
|
|
|
<td>
|
|
|
|
<?php if (isset($event['event_base_score'])) : ?>
|
|
|
|
<table class="table-xcondensed no-border">
|
|
|
|
<?php foreach ($event['event_base_score'] as $bs) : ?>
|
|
|
|
<tr>
|
|
|
|
<td style="line-height: 14px;"><i class="no-overflow" style="max-width: 12em;" title="<?= h($bs['DecayingModel']['name']); ?>"><?= h($bs['DecayingModel']['name']); ?>:</i></td>
|
|
|
|
<td style="line-height: 14px;"><b style="color: <?= !empty($bs['decayed']) ? '#b94a48' : '#468847' ?>;"><?= round($bs['base_score'], 2) ?></b></td>
|
|
|
|
</tr>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</table>
|
|
|
|
<?php else : ?>
|
|
|
|
|
|
|
|
<?php endif; ?>
|
|
|
|
</td>
|
|
|
|
<?php endif; ?>
|
|
|
|
<td><a href="<?= sprintf('%s/events/view/%s', $baseurl, h($event['Event']['uuid'])) ?>"><?= h($event['Event']['info']) ?></a></td>
|
|
|
|
</tr>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
<?php else : ?>
|
|
|
|
<p><?= __('No events.') ?></p>
|
|
|
|
<?php endif; ?>
|
2022-08-31 14:45:53 +02:00
|
|
|
<?php endif; ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
</div>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?php endif; // detailed-summary-full ?>
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php if ($this->fetch('trending-summary')) : ?>
|
|
|
|
<?= $this->fetch('trending-summary'); ?>
|
|
|
|
<?php else : ?>
|
|
|
|
<div class="panel">
|
|
|
|
<?= $trending_summary; ?>
|
|
|
|
</div>
|
|
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
<?php if ($this->fetch('aggregated-context')) : ?>
|
2022-08-30 14:10:01 +02:00
|
|
|
<?= $this->fetch('aggregated-context'); ?>
|
2022-09-08 10:59:47 +02:00
|
|
|
<?php else : ?>
|
|
|
|
<div class="panel">
|
2022-08-30 14:10:01 +02:00
|
|
|
<?= $aggregated_context; ?>
|
|
|
|
</div>
|
|
|
|
<?php endif; ?>
|
|
|
|
|
2022-09-08 10:59:47 +02:00
|
|
|
<?= $this->fetch('content'); ?>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.mw-50 {
|
|
|
|
max-width: 50%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.panel {
|
|
|
|
padding: 4px 10px;
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
border-radius: 3px;
|
2022-09-08 13:33:08 +02:00
|
|
|
background-color: #cccccc22;
|
2022-09-08 10:59:47 +02:00
|
|
|
margin-bottom: 20px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.tag {
|
|
|
|
display: inline-block;
|
|
|
|
padding: 2px 4px;
|
|
|
|
font-size: 12px;
|
|
|
|
font-weight: bold;
|
|
|
|
line-height: 14px;
|
|
|
|
margin-right: 2px;
|
|
|
|
border-radius: 3px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.no-overflow {
|
|
|
|
display: inline-block;
|
|
|
|
white-space: nowrap;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
overflow: hidden
|
|
|
|
}
|
|
|
|
|
|
|
|
.table {
|
|
|
|
width: 100%;
|
|
|
|
margin-bottom: 20px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table.table-condensed td,
|
|
|
|
.table.table-condensed th {
|
|
|
|
padding: 4px 5px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table-xcondensed td,
|
|
|
|
.table-xcondensed th {
|
|
|
|
padding: 0px 2px !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table th,
|
|
|
|
.table td {
|
|
|
|
padding: 8px;
|
|
|
|
line-height: 20px;
|
|
|
|
text-align: left;
|
|
|
|
vertical-align: top;
|
|
|
|
border-top: 1px solid #dddddd;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table thead th {
|
|
|
|
vertical-align: bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table caption+thead tr:first-child th,
|
|
|
|
.table caption+thead tr:first-child td,
|
|
|
|
.table colgroup+thead tr:first-child th,
|
|
|
|
.table colgroup+thead tr:first-child td,
|
|
|
|
.table thead:first-child tr:first-child th,
|
|
|
|
.table thead:first-child tr:first-child td {
|
|
|
|
border-top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
table.no-border td {
|
|
|
|
border-top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.table.no-border tbody+tbody {
|
|
|
|
border-top: 0;
|
|
|
|
}
|
|
|
|
</style>
|