diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php
index 691b59d..a01aee2 100644
--- a/application/forms/AddNodeForm.php
+++ b/application/forms/AddNodeForm.php
@@ -210,7 +210,7 @@ class AddNodeForm extends QuickForm
$this->addServiceOverrideCheckbox();
if ($this->getSentValue('service_override') === '1') {
- $this->addServiceOverrideElements();
+ $this->addServiceOverrideElement();
}
} else {
$this->setSubmitLabel($this->translate('Next'));
@@ -268,23 +268,12 @@ class AddNodeForm extends QuickForm
]);
}
- protected function addServiceOverrideElements()
+ protected function addServiceOverrideElement()
{
- $elements = [];
- foreach ($this->enumServiceStateList() as $state => $stateName) {
- if ($state === 0) {
- continue;
- }
- $this->addElement('select', $stateName, [
- 'label' => $this->translate($stateName),
- 'ignore' => true,
- 'multiOptions' => $this->optionalEnum($this->enumServiceStateList()),
- ]);
- $elements[] = $stateName;
- }
-
- $this->addSimpleDisplayGroup($elements, 'override_group', [
- 'legend' => $this->translate('State Overrides')
+ $this->addElement('stateOverrides', 'stateOverrides', [
+ 'required' => true,
+ 'label' => $this->translate('State Overrides'),
+ 'states' => $this->enumServiceStateList()
]);
}
@@ -439,21 +428,6 @@ class AddNodeForm extends QuickForm
return $serviceStateList;
}
- protected function statesToString()
- {
- $stateString = null;
- foreach ($this->enumServiceStateList() as $state => $stateName) {
- if ($this->getValue($stateName) !== null && $this->getValue($stateName) !== '') {
- if ($stateString !== null) {
- $stateString .= ',';
- }
- $stateString .= $state . '-' . $this->getValue($stateName);
- }
- }
-
- return $stateString;
- }
-
protected function hasProcesses()
{
return count($this->enumProcesses()) > 0;
@@ -528,15 +502,15 @@ class AddNodeForm extends QuickForm
$changes = ProcessChanges::construct($this->bp, $this->session);
switch ($this->getValue('node_type')) {
case 'service':
- if ($this->statesToString() !== null) {
- $services = [];
- foreach ($this->getValue('children') as $service) {
- $services[] = $service . ':' . $this->statesToString();
- }
- $changes->addChildrenToNode($services, $this->parent);
- } else {
- $changes->addChildrenToNode($this->getValue('children'), $this->parent);
+ $properties = $this->getValues();
+ unset($properties['children']);
+
+ $services = [];
+ foreach ($this->getValue('children') as $service) {
+ $services[$service] = $properties;
}
+
+ $changes->addChildrenToNode($services, $this->parent);
break;
case 'host':
case 'process':
diff --git a/application/forms/EditNodeForm.php b/application/forms/EditNodeForm.php
index 438ad59..2d60d88 100644
--- a/application/forms/EditNodeForm.php
+++ b/application/forms/EditNodeForm.php
@@ -36,8 +36,6 @@ class EditNodeForm extends QuickForm
protected $host;
- protected $statesOverride = [];
-
/** @var SessionNamespace */
protected $session;
@@ -45,8 +43,7 @@ class EditNodeForm extends QuickForm
{
$this->host = substr($this->getNode()->getName(), 0, strpos($this->getNode()->getName(), ';'));
if ($this->isService()) {
- $this->service = $this->getNode()->getShortName();
- $this->statesOverride = $this->getNode()->getStatesOverride();
+ $this->service = substr($this->getNode()->getName(), strpos($this->getNode()->getName(), ';') + 1);
}
$view = $this->getView();
@@ -159,6 +156,7 @@ class EditNodeForm extends QuickForm
if ($this->hasParentNode()) {
$this->addElement('hidden', 'node_type', [
'disabled' => true,
+ 'ignore' => true,
'decorators' => ['ViewHelper'],
'value' => $monitoredNodeType
]);
@@ -194,14 +192,14 @@ class EditNodeForm extends QuickForm
if ($this->getSentValue('hosts') === null) {
$this->addServicesElement($this->host);
$this->addServiceOverrideCheckbox();
- if (!empty($this->statesOverride) || $this->getSentValue('service_override') === '1') {
- $this->addServiceOverrideElements();
+ if (! empty($this->node->getStateOverrides()) || $this->getSentValue('service_override') === '1') {
+ $this->addServiceOverrideElement();
}
} elseif ($host = $this->getSentValue('hosts')) {
$this->addServicesElement($host);
$this->addServiceOverrideCheckbox();
if ($this->getSentValue('service_override') === '1') {
- $this->addServiceOverrideElements();
+ $this->addServiceOverrideElement();
}
} else {
$this->setSubmitLabel($this->translate('Next'));
@@ -225,23 +223,11 @@ class EditNodeForm extends QuickForm
{
$this->addElement('select', 'children', array(
'required' => true,
- 'value' => $this->service,
+ 'value' => $this->getNode()->getName(),
'multiOptions' => $this->enumServiceList($host),
'label' => $this->translate('Service'),
'description' => $this->translate('The service for this business process node'),
- 'validators' => [
- ['Callback', true, [
- 'callback' => function ($value) {
- if ($this->node->getShortName() === $value) {
- return true;
- }
- return ! $this->parent->hasMatchingChild($value);
- },
- 'messages' => [
- 'callbackValue' => $this->translate('%value% is already defined in this process')
- ]
- ]]
- ]
+ 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]]
));
}
@@ -250,30 +236,19 @@ class EditNodeForm extends QuickForm
$this->addElement('checkbox', 'service_override', [
'ignore' => true,
'class' => 'autosubmit',
- 'value' => ! empty($this->statesOverride) ? '1' : null,
+ 'value' => ! empty($this->node->getStateOverrides()),
'label' => $this->translate('Override Service State'),
'description' => $this->translate('Enable service state overrides')
]);
}
- protected function addServiceOverrideElements()
+ protected function addServiceOverrideElement()
{
- $elements = [];
- foreach ($this->enumServiceStateList() as $state => $stateName) {
- if ($state == 0) {
- continue;
- }
- $this->addElement('select', $stateName, [
- 'label' => $this->translate($stateName),
- 'value' => isset($this->statesOverride[$state]) ? $this->statesOverride[$state] : null,
- 'ignore' => true,
- 'multiOptions' => $this->optionalEnum($this->enumServiceStateList()),
- ]);
- $elements[] = $stateName;
- }
-
- $this->addSimpleDisplayGroup($elements, 'override_group', [
- 'legend' => $this->translate('State Overrides')
+ $this->addElement('stateOverrides', 'stateOverrides', [
+ 'required' => true,
+ 'states' => $this->enumServiceStateList(),
+ 'value' => $this->node->getStateOverrides(),
+ 'label' => $this->translate('State Overrides')
]);
}
@@ -409,21 +384,6 @@ class EditNodeForm extends QuickForm
return $serviceStateList;
}
- protected function statesToString()
- {
- $stateString = null;
- foreach ($this->enumServiceStateList() as $state => $stateName) {
- if ($this->getValue($stateName) !== null && $this->getValue($stateName) !== '') {
- if ($stateString !== null) {
- $stateString .= ',';
- }
- $stateString .= $state . '-' . $this->getValue($stateName);
- }
- }
-
- return $stateString;
- }
-
protected function hasProcesses()
{
return count($this->enumProcesses()) > 0;
@@ -489,14 +449,10 @@ class EditNodeForm extends QuickForm
switch ($this->getValue('node_type')) {
case 'service':
- if ($this->statesToString() !== null) {
- $changes->addChildrenToNode(
- $this->getValue('children') . ':' . $this->statesToString(),
- $this->parent
- );
- } else {
- $changes->addChildrenToNode($this->getValue('children'), $this->parent);
- }
+ $properties = $this->getValues();
+ unset($properties['children']);
+ $services = [$this->getValue('children') => $properties];
+ $changes->addChildrenToNode($services, $this->parent);
break;
case 'host':
case 'process':
diff --git a/application/views/helpers/FormStateOverrides.php b/application/views/helpers/FormStateOverrides.php
new file mode 100644
index 0000000..74ed2f4
--- /dev/null
+++ b/application/views/helpers/FormStateOverrides.php
@@ -0,0 +1,40 @@
+ $label) {
+ if ($state === 0) {
+ continue;
+ }
+
+ $chosen = $state;
+ if (isset($value[$state])) {
+ $chosen = $value[$state];
+ }
+
+ $options = [$state => t('Keep actual state')] + $states;
+
+ $html .= '';
+ }
+
+ return $html;
+ }
+}
diff --git a/library/Businessprocess/BpConfig.php b/library/Businessprocess/BpConfig.php
index 96a0a7d..c49d262 100644
--- a/library/Businessprocess/BpConfig.php
+++ b/library/Businessprocess/BpConfig.php
@@ -460,21 +460,16 @@ class BpConfig
return array_key_exists($name, $this->root_nodes);
}
- public function createService($host, $service, $statesOverride = null)
+ public function createService($host, $service)
{
$node = new ServiceNode(
(object) array(
'hostname' => $host,
- 'service' => $service,
- 'statesOverride'=> $statesOverride
+ 'service' => $service
)
);
$node->setBpConfig($this);
- if (isset($statesOverride)) {
- $this->nodes[$host . ';' . $service . ':' . $statesOverride] = $node;
- } else {
- $this->nodes[$host . ';' . $service] = $node;
- }
+ $this->nodes[$host . ';' . $service] = $node;
$this->hosts[$host] = true;
return $node;
}
@@ -662,19 +657,6 @@ class BpConfig
);
}
- public function getMatchingNodeNams($name)
- {
- $matching = [];
-
- foreach ($this->nodes as $nodeName => $node) {
- if ($name === $node->getShortName()) {
- $matching[] = $nodeName;
- }
- }
-
- return $matching;
- }
-
/**
* @return BpNode
*/
diff --git a/library/Businessprocess/BpNode.php b/library/Businessprocess/BpNode.php
index b6f3721..9aeaab8 100644
--- a/library/Businessprocess/BpNode.php
+++ b/library/Businessprocess/BpNode.php
@@ -142,11 +142,6 @@ class BpNode extends Node
return in_array($name, $this->getChildNames());
}
- public function hasMatchingChild($name)
- {
- return in_array($name, $this->getChildShortNames());
- }
-
public function removeChild($name)
{
if (($key = array_search($name, $this->getChildNames())) !== false) {
@@ -503,20 +498,6 @@ class BpNode extends Node
return $this->children;
}
- protected function getChildShortNames()
- {
- $ChidrenShortNames = array();
-
- foreach ($this->getChildren() as $child) {
- $name = $child->getShortName();
- array_push($ChidrenShortNames, $name);
- }
-
- return $ChidrenShortNames;
- }
-
-
-
/**
* Reorder this node's children, in case manual order is not applied
*/
diff --git a/library/Businessprocess/Modification/NodeAddChildrenAction.php b/library/Businessprocess/Modification/NodeAddChildrenAction.php
index 4b9988b..8f9c5e0 100644
--- a/library/Businessprocess/Modification/NodeAddChildrenAction.php
+++ b/library/Businessprocess/Modification/NodeAddChildrenAction.php
@@ -31,19 +31,26 @@ class NodeAddChildrenAction extends NodeAction
{
$node = $config->getBpNode($this->getNodeName());
- foreach ($this->children as $name) {
+ foreach ($this->children as $name => $properties) {
+ if (is_int($name)) {
+ // TODO: This may be removed once host nodes also have properties
+ $name = $properties;
+ }
+
if (! $config->hasNode($name) || $config->getNode($name)->getBpConfig()->getName() !== $config->getName()) {
if (strpos($name, ';') !== false) {
- if (strpos($name, ':') !== false) {
- list($host, $service, $statesOverride) = preg_split('~[;:]~', $name, 3);
- $config->createService($host, $service, $statesOverride);
- } else {
- list($host, $service) = preg_split('/;/', $name, 2);
+ list($host, $service) = preg_split('/;/', $name, 2);
- if ($service === 'Hoststatus') {
- $config->createHost($host);
- } else {
- $config->createService($host, $service);
+ if ($service === 'Hoststatus') {
+ $child = $config->createHost($host);
+ } else {
+ $child = $config->createService($host, $service);
+ }
+
+ if (is_array($properties) && !empty($properties)) {
+ foreach ($properties as $key => $value) {
+ $func = 'set' . ucfirst($key);
+ $child->$func($value);
}
}
} elseif ($name[0] === '@' && strpos($name, ':') !== false) {
diff --git a/library/Businessprocess/Node.php b/library/Businessprocess/Node.php
index 5c8f0dd..bec3346 100644
--- a/library/Businessprocess/Node.php
+++ b/library/Businessprocess/Node.php
@@ -46,7 +46,7 @@ abstract class Node
self::NODE_EMPTY => 0
);
- protected $stateOverride = [];
+ protected $stateOverrides = [];
/** @var string Alias of the node */
protected $alias;
@@ -199,26 +199,16 @@ abstract class Node
return $this;
}
- protected function setStateOverride($state, $oveRrideState)
+ public function setStateOverrides(array $overrides)
{
- $this->stateOverride[(int) $state] = (int) $oveRrideState;
+ $this->stateOverrides = $overrides;
+
+ return $this;
}
- public function setStatesOverride($statesOverrideString)
+ public function getStateOverrides()
{
- $overrides = explode(',', $statesOverrideString);
-
- foreach ($overrides as $overrideState) {
- if (strpos($overrideState, '-') !== false) {
- list($key, $value) = explode('-', $overrideState);
- $this->setStateOverride($key, $value);
- }
- }
- }
-
- public function getStatesOverride()
- {
- return $this->stateOverride;
+ return $this->stateOverrides;
}
/**
@@ -270,8 +260,8 @@ abstract class Node
);
}
- if (isset($this->stateOverride[$this->state])) {
- return $this->stateOverride[$this->state];
+ if (isset($this->stateOverrides[$this->state])) {
+ return $this->stateOverrides[$this->state];
} else {
return $this->state;
}
@@ -406,11 +396,6 @@ abstract class Node
return $this;
}
- public function getShortName()
- {
- return $this->name;
- }
-
public function hasParents()
{
return count($this->parents) > 0;
diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php
index 6b3e4fe..3d58075 100644
--- a/library/Businessprocess/Renderer/TreeRenderer.php
+++ b/library/Businessprocess/Renderer/TreeRenderer.php
@@ -154,7 +154,7 @@ class TreeRenderer extends Renderer
{
$statesOverrights = [];
- $states = $node->getStatesOverride();
+ $states = $node->getStateOverrides();
foreach ($states as $originalState => $overrideState) {
$statesOverrights[] = (new StateBall(strtolower($node->getStateName($originalState))))->addAttributes([
'title' => sprintf(
@@ -290,7 +290,7 @@ class TreeRenderer extends Renderer
'class' => 'left-side',
]);
- if (!empty($node->getStatesOverride())) {
+ if (! empty($node->getStateOverrides())) {
$leftAlign->add($this->getNodeStateOverride($node));
}
diff --git a/library/Businessprocess/ServiceNode.php b/library/Businessprocess/ServiceNode.php
index fc308f6..6160bce 100644
--- a/library/Businessprocess/ServiceNode.php
+++ b/library/Businessprocess/ServiceNode.php
@@ -19,12 +19,7 @@ class ServiceNode extends MonitoredNode
public function __construct($object)
{
- if (isset($object->statesOverride)) {
- $this->name = $object->hostname . ';' . $object->service . ':' . $object->statesOverride;
- $this->setStatesOverride($object->statesOverride);
- } else {
- $this->name = $object->hostname . ';' . $object->service;
- }
+ $this->name = $object->hostname . ';' . $object->service;
$this->hostname = $object->hostname;
$this->service = $object->service;
if (isset($object->state)) {
@@ -72,11 +67,6 @@ class ServiceNode extends MonitoredNode
{
return $this->getHostAlias() . ': ' . $this->alias;
}
-
- public function getShortName()
- {
- return $this->hostname . ';' . $this->service;
- }
public function getUrl()
{
diff --git a/library/Businessprocess/State/MonitoringState.php b/library/Businessprocess/State/MonitoringState.php
index beea0af..d317528 100644
--- a/library/Businessprocess/State/MonitoringState.php
+++ b/library/Businessprocess/State/MonitoringState.php
@@ -122,27 +122,24 @@ class MonitoringState
$key .= ';Hoststatus';
}
- $nodesNames = $config->getMatchingNodeNams($key);
- foreach ($nodesNames as $nodeName) {
- // We fetch more states than we need, so skip unknown ones
- if (! $config->hasNode($nodeName)) {
- return;
- }
+ // We fetch more states than we need, so skip unknown ones
+ if (! $config->hasNode($key)) {
+ return;
+ }
- $node = $config->getNode($nodeName);
+ $node = $config->getNode($key);
- if ($row->state !== null) {
- $node->setState($row->state)->setMissing(false);
- }
- if ($row->last_state_change !== null) {
- $node->setLastStateChange($row->last_state_change);
- }
- if ((int) $row->in_downtime === 1) {
- $node->setDowntime(true);
- }
- if ((int) $row->ack === 1) {
- $node->setAck(true);
- }
+ if ($row->state !== null) {
+ $node->setState($row->state)->setMissing(false);
+ }
+ if ($row->last_state_change !== null) {
+ $node->setLastStateChange($row->last_state_change);
+ }
+ if ((int) $row->in_downtime === 1) {
+ $node->setDowntime(true);
+ }
+ if ((int) $row->ack === 1) {
+ $node->setAck(true);
}
$node->setAlias($row->display_name);
diff --git a/library/Businessprocess/Storage/LegacyConfigParser.php b/library/Businessprocess/Storage/LegacyConfigParser.php
index fcf382c..1afc256 100644
--- a/library/Businessprocess/Storage/LegacyConfigParser.php
+++ b/library/Businessprocess/Storage/LegacyConfigParser.php
@@ -233,6 +233,24 @@ class LegacyConfigParser
$bp->getBpNode($name)->setInfoUrl($url);
}
+ protected function parseStateOverrides(&$line, BpConfig $bp)
+ {
+ // state_overrides !|n-n[,n-n]!|n-n[,n-n]
+ $segments = preg_split('~\s*!\s*~', substr($line, 16));
+ $node = $bp->getNode(array_shift($segments));
+ foreach ($segments as $overrideDef) {
+ list($childName, $overrides) = preg_split('~\s*\|\s*~', $overrideDef, 2);
+
+ $stateOverrides = [];
+ foreach (preg_split('~\s*,\s*~', $overrides) as $override) {
+ list($from, $to) = preg_split('~\s*-\s*~', $override, 2);
+ $stateOverrides[(int) $from] = (int) $to;
+ }
+
+ $node->getChildByName($childName)->setStateOverrides($stateOverrides);
+ }
+ }
+
protected function parseExtraLine(&$line, $typeLength, BpConfig $bp)
{
$type = substr($line, 0, $typeLength);
@@ -251,6 +269,9 @@ class LegacyConfigParser
case 'info_url':
$this->parseInfoUrl($line, $bp);
break;
+ case 'state_overrides':
+ $this->parseStateOverrides($line, $bp);
+ break;
case 'template':
// compat, ignoring for now
break;
@@ -282,9 +303,9 @@ class LegacyConfigParser
return;
}
- // Space found in the first 14 cols? Might be a line with extra information
+ // Space found in the first 16 cols? Might be a line with extra information
$pos = strpos($line, ' ');
- if ($pos !== false && $pos < 14) {
+ if ($pos !== false && $pos < 16) {
if ($this->parseExtraLine($line, $pos, $bp)) {
return;
}
@@ -335,17 +356,11 @@ class LegacyConfigParser
if ($bp->hasNode($val)) {
$node->addChild($bp->getNode($val));
} else {
- if (strpos($val, ':') !== false) {
- list($host, $service, $statesOverride) = preg_split('~[;:]~', $val, 3);
- $node->addChild($bp->createService($host, $service, $statesOverride));
+ list($host, $service) = preg_split('~;~', $val, 2);
+ if ($service === 'Hoststatus') {
+ $node->addChild($bp->createHost($host));
} else {
- list($host, $service) = preg_split('~;~', $val, 2);
-
- if ($service === 'Hoststatus') {
- $node->addChild($bp->createHost($host));
- } else {
- $node->addChild($bp->createService($host, $service));
- }
+ $node->addChild($bp->createService($host, $service));
}
}
} elseif ($val[0] === '@') {
diff --git a/library/Businessprocess/Storage/LegacyConfigRenderer.php b/library/Businessprocess/Storage/LegacyConfigRenderer.php
index 77a1d13..eba26bc 100644
--- a/library/Businessprocess/Storage/LegacyConfigRenderer.php
+++ b/library/Businessprocess/Storage/LegacyConfigRenderer.php
@@ -158,6 +158,7 @@ class LegacyConfigRenderer
public static function renderSingleBpNode(BpNode $node)
{
return static::renderExpression($node)
+ . static::renderStateOverrides($node)
. static::renderDisplay($node)
. static::renderInfoUrl($node);
}
@@ -214,6 +215,27 @@ class LegacyConfigRenderer
}
}
+ public static function renderStateOverrides(BpNode $node)
+ {
+ $stateOverrides = '';
+ foreach ($node->getChildren() as $child) {
+ $overrides = [];
+ foreach ($child->getStateOverrides() as $from => $to) {
+ $overrides[] = sprintf('%d-%d', $from, $to);
+ }
+
+ if (! empty($overrides)) {
+ $stateOverrides .= '!' . $child->getName() . '|' . join(',', $overrides);
+ }
+ }
+
+ if (! $stateOverrides) {
+ return '';
+ }
+
+ return 'state_overrides ' . $node->getName() . $stateOverrides . "\n";
+ }
+
/**
* @param BpNode $node
* @return string
diff --git a/library/Businessprocess/Web/Form/Element/StateOverrides.php b/library/Businessprocess/Web/Form/Element/StateOverrides.php
new file mode 100644
index 0000000..49cb233
--- /dev/null
+++ b/library/Businessprocess/Web/Form/Element/StateOverrides.php
@@ -0,0 +1,52 @@
+states = $states;
+
+ return $this;
+ }
+
+ /**
+ * Get the overridable states
+ *
+ * @return array
+ */
+ public function getStates()
+ {
+ return $this->states;
+ }
+
+ public function init()
+ {
+ $this->setIsArray(true);
+ }
+
+ public function setValue($value)
+ {
+ $cleanedValue = [];
+ foreach ($value as $from => $to) {
+ if ((int) $from !== (int) $to) {
+ $cleanedValue[$from] = $to;
+ }
+ }
+
+ return parent::setValue($cleanedValue);
+ }
+}
diff --git a/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php b/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php
index ecdd345..9676de0 100644
--- a/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php
+++ b/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php
@@ -43,7 +43,7 @@ class NoDuplicateChildrenValidator extends Zend_Validate_Abstract
} elseif ($this->form instanceof EditNodeForm && $this->form->getNode()->getName() === $value) {
$found = false;
} else {
- $found = $this->parent->hasMatchingChild($value);
+ $found = $this->parent->hasChild($value);
}
if (! $found) {
diff --git a/public/css/module.less b/public/css/module.less
index 2da19a2..8d1dcf6 100644
--- a/public/css/module.less
+++ b/public/css/module.less
@@ -962,37 +962,27 @@ form dt label {
}
}
-fieldset.collapsed {
- dd, dt, ul, div {
- display: none;
- }
- }
+#stateOverrides-element {
+ display: inline-table;
+ table-layout: fixed;
+ border-spacing: .5em;
+ padding: 0;
-fieldset {
- margin-top: 15px;
- padding: 0 0 1.5em 0;
- border: none;
+ label {
+ display: table-row;
- legend {
- margin: 0em 0 0.5em 0;
- font-size: 1em;
- box-shadow: 0 3px 4px -4px rgba(0,0,0,0.2);
- font-weight: bold;
- width: 100%;
- padding-left: 0.5em;
- line-height: 2em;
- user-select: none;
-
- &:hover {
- border-color: @text-color;
- }
- }
- dd, dt, ul, div {
- display: none;
+ span, select {
+ display: table-cell;
}
- margin-bottom: 0.2em;
- padding-bottom: 0;
+ span {
+ width: 10em;
+ }
+
+ select {
+ width: 26em;
+ }
+ }
}
form fieldset {