From 98b6b2c6d03f85446f9fc9b77bb30a1ef37b6892 Mon Sep 17 00:00:00 2001 From: Christian Menapace Date: Mon, 20 May 2019 12:08:06 +0200 Subject: [PATCH 1/6] Add Service Override --- application/forms/AddNodeForm.php | 75 ++++++++++++- application/forms/EditNodeForm.php | 100 +++++++++++++++++- library/Businessprocess/BpConfig.php | 24 ++++- library/Businessprocess/BpNode.php | 19 ++++ .../Modification/NodeAddChildrenAction.php | 15 ++- library/Businessprocess/Node.php | 47 ++++++++ .../Renderer/TileRenderer/NodeTile.php | 9 ++ .../Businessprocess/Renderer/TreeRenderer.php | 57 +++++++++- library/Businessprocess/ServiceNode.php | 12 ++- .../Businessprocess/State/MonitoringState.php | 35 +++--- .../Storage/LegacyConfigParser.php | 14 ++- .../NoDuplicateChildrenValidator.php | 2 +- public/css/module.less | 58 ++++++++-- 13 files changed, 424 insertions(+), 43 deletions(-) diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php index 591f37a..691b59d 100644 --- a/application/forms/AddNodeForm.php +++ b/application/forms/AddNodeForm.php @@ -207,6 +207,11 @@ class AddNodeForm extends QuickForm $this->addHostElement(); if ($host = $this->getSentValue('host')) { $this->addServicesElement($host); + $this->addServiceOverrideCheckbox(); + + if ($this->getSentValue('service_override') === '1') { + $this->addServiceOverrideElements(); + } } else { $this->setSubmitLabel($this->translate('Next')); } @@ -253,6 +258,36 @@ class AddNodeForm extends QuickForm ]); } + protected function addServiceOverrideCheckbox() + { + $this->addElement('checkbox', 'service_override', [ + 'ignore' => true, + 'class' => 'autosubmit', + 'label' => $this->translate('Override Service State'), + 'description' => $this->translate('Enable service state overrides') + ]); + } + + protected function addServiceOverrideElements() + { + $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') + ]); + } + protected function selectProcess() { if ($this->hasParentNode()) { @@ -391,6 +426,34 @@ class AddNodeForm extends QuickForm return $services; } + protected function enumServiceStateList() + { + $serviceStateList = [ + 0 => $this->translate('OK'), + 1 => $this->translate('WARNING'), + 2 => $this->translate('CRITICAL'), + 3 => $this->translate('UNKNOWN'), + 99 => $this->translate('PENDING'), + ]; + + 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; @@ -464,8 +527,18 @@ class AddNodeForm extends QuickForm { $changes = ProcessChanges::construct($this->bp, $this->session); switch ($this->getValue('node_type')) { - case 'host': 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); + } + break; + case 'host': case 'process': if ($this->hasParentNode()) { $changes->addChildrenToNode($this->getValue('children'), $this->parent); diff --git a/application/forms/EditNodeForm.php b/application/forms/EditNodeForm.php index 429a8f2..438ad59 100644 --- a/application/forms/EditNodeForm.php +++ b/application/forms/EditNodeForm.php @@ -36,6 +36,8 @@ class EditNodeForm extends QuickForm protected $host; + protected $statesOverride = []; + /** @var SessionNamespace */ protected $session; @@ -43,7 +45,8 @@ class EditNodeForm extends QuickForm { $this->host = substr($this->getNode()->getName(), 0, strpos($this->getNode()->getName(), ';')); if ($this->isService()) { - $this->service = substr($this->getNode()->getName(), strpos($this->getNode()->getName(), ';') + 1); + $this->service = $this->getNode()->getShortName(); + $this->statesOverride = $this->getNode()->getStatesOverride(); } $view = $this->getView(); @@ -190,8 +193,16 @@ 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(); + } } elseif ($host = $this->getSentValue('hosts')) { $this->addServicesElement($host); + $this->addServiceOverrideCheckbox(); + if ($this->getSentValue('service_override') === '1') { + $this->addServiceOverrideElements(); + } } else { $this->setSubmitLabel($this->translate('Next')); } @@ -214,14 +225,58 @@ class EditNodeForm extends QuickForm { $this->addElement('select', 'children', array( 'required' => true, - 'value' => $this->getNode()->getName(), + 'value' => $this->service, 'multiOptions' => $this->enumServiceList($host), 'label' => $this->translate('Service'), 'description' => $this->translate('The service for this business process node'), - 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] + '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') + ] + ]] + ] )); } + protected function addServiceOverrideCheckbox() + { + $this->addElement('checkbox', 'service_override', [ + 'ignore' => true, + 'class' => 'autosubmit', + 'value' => ! empty($this->statesOverride) ? '1' : null, + 'label' => $this->translate('Override Service State'), + 'description' => $this->translate('Enable service state overrides') + ]); + } + + protected function addServiceOverrideElements() + { + $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') + ]); + } + protected function selectProcess() { $this->addElement('multiselect', 'children', array( @@ -341,6 +396,34 @@ class EditNodeForm extends QuickForm return $services; } + protected function enumServiceStateList() + { + $serviceStateList = [ + 0 => $this->translate('OK'), + 1 => $this->translate('WARNING'), + 2 => $this->translate('CRITICAL'), + 3 => $this->translate('UNKNOWN'), + 99 => $this->translate('PENDING'), + ]; + + 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; @@ -405,8 +488,17 @@ class EditNodeForm extends QuickForm $changes->deleteNode($this->node, $this->parent->getName()); switch ($this->getValue('node_type')) { - case 'host': case 'service': + if ($this->statesToString() !== null) { + $changes->addChildrenToNode( + $this->getValue('children') . ':' . $this->statesToString(), + $this->parent + ); + } else { + $changes->addChildrenToNode($this->getValue('children'), $this->parent); + } + break; + case 'host': case 'process': $changes->addChildrenToNode($this->getValue('children'), $this->parent); break; diff --git a/library/Businessprocess/BpConfig.php b/library/Businessprocess/BpConfig.php index c49d262..96a0a7d 100644 --- a/library/Businessprocess/BpConfig.php +++ b/library/Businessprocess/BpConfig.php @@ -460,16 +460,21 @@ class BpConfig return array_key_exists($name, $this->root_nodes); } - public function createService($host, $service) + public function createService($host, $service, $statesOverride = null) { $node = new ServiceNode( (object) array( 'hostname' => $host, - 'service' => $service + 'service' => $service, + 'statesOverride'=> $statesOverride ) ); $node->setBpConfig($this); - $this->nodes[$host . ';' . $service] = $node; + if (isset($statesOverride)) { + $this->nodes[$host . ';' . $service . ':' . $statesOverride] = $node; + } else { + $this->nodes[$host . ';' . $service] = $node; + } $this->hosts[$host] = true; return $node; } @@ -657,6 +662,19 @@ 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 9aeaab8..b6f3721 100644 --- a/library/Businessprocess/BpNode.php +++ b/library/Businessprocess/BpNode.php @@ -142,6 +142,11 @@ 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) { @@ -498,6 +503,20 @@ 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 5d5ab29..4b9988b 100644 --- a/library/Businessprocess/Modification/NodeAddChildrenAction.php +++ b/library/Businessprocess/Modification/NodeAddChildrenAction.php @@ -34,12 +34,17 @@ class NodeAddChildrenAction extends NodeAction foreach ($this->children as $name) { if (! $config->hasNode($name) || $config->getNode($name)->getBpConfig()->getName() !== $config->getName()) { if (strpos($name, ';') !== false) { - list($host, $service) = preg_split('/;/', $name, 2); - - if ($service === 'Hoststatus') { - $config->createHost($host); + if (strpos($name, ':') !== false) { + list($host, $service, $statesOverride) = preg_split('~[;:]~', $name, 3); + $config->createService($host, $service, $statesOverride); } else { - $config->createService($host, $service); + list($host, $service) = preg_split('/;/', $name, 2); + + if ($service === 'Hoststatus') { + $config->createHost($host); + } else { + $config->createService($host, $service); + } } } elseif ($name[0] === '@' && strpos($name, ':') !== false) { list($configName, $nodeName) = preg_split('~:\s*~', substr($name, 1), 2); diff --git a/library/Businessprocess/Node.php b/library/Businessprocess/Node.php index 7849a7c..5c8f0dd 100644 --- a/library/Businessprocess/Node.php +++ b/library/Businessprocess/Node.php @@ -46,6 +46,8 @@ abstract class Node self::NODE_EMPTY => 0 ); + protected $stateOverride = []; + /** @var string Alias of the node */ protected $alias; @@ -197,6 +199,28 @@ abstract class Node return $this; } + protected function setStateOverride($state, $oveRrideState) + { + $this->stateOverride[(int) $state] = (int) $oveRrideState; + } + + public function setStatesOverride($statesOverrideString) + { + $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; + } + /** * Forget my state * @@ -246,6 +270,24 @@ abstract class Node ); } + if (isset($this->stateOverride[$this->state])) { + return $this->stateOverride[$this->state]; + } else { + return $this->state; + } + } + + public function getRealState() + { + if ($this->state === null) { + throw new ProgrammingError( + sprintf( + 'Node %s is unable to retrieve it\'s state', + $this->name + ) + ); + } + return $this->state; } @@ -364,6 +406,11 @@ 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/TileRenderer/NodeTile.php b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php index 8c16ed5..7cb0c81 100644 --- a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php +++ b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php @@ -113,6 +113,15 @@ class NodeTile extends BaseHtmlElement )); } + if ($node instanceof ServiceNode && $node->getRealState() !== $node->getState()) { + $this->add((new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName($node->getRealState()) + ) + ])); + } + if ($node instanceof BpNode && !$renderer->isBreadcrumb()) { $this->add(Html::tag( 'p', diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php index 9322c26..6b3e4fe 100644 --- a/library/Businessprocess/Renderer/TreeRenderer.php +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -136,6 +136,45 @@ class TreeRenderer extends Renderer return $icons; } + public function getNodeRealState(Node $node) + { + $realState = []; + $realState[] = Html::tag('i', ['class' => 'icon icon-flash']); + $realState[] = (new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName($node->getRealState()) + ) + ]); + + return $realState; + } + + public function getNodeStateOverride(Node $node) + { + $statesOverrights = []; + + $states = $node->getStatesOverride(); + foreach ($states as $originalState => $overrideState) { + $statesOverrights[] = (new StateBall(strtolower($node->getStateName($originalState))))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName($originalState) + ) + ]); + $statesOverrights[] = Html::tag('i', ['class' => 'icon icon-right-small']); + $statesOverrights[] = (new StateBall(strtolower($node->getStateName($overrideState))))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName($overrideState) + ), + 'class' => 'last' + ]); + } + + return $statesOverrights; + } + /** * @param BpConfig $bp * @param Node $node @@ -243,10 +282,24 @@ class TreeRenderer extends Renderer $link->getAttributes()->set('data-base-target', '_next'); $li->add($link); - if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) { - $li->add($this->getActionIcons($bp, $node)); + if ($node->getRealState() !== $node->getState()) { + $li->add($this->getNodeRealState($node)); } + $leftAlign = Html::tag('div', [ + 'class' => 'left-side', + ]); + + if (!empty($node->getStatesOverride())) { + $leftAlign->add($this->getNodeStateOverride($node)); + } + + if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) { + $leftAlign->add($this->getActionIcons($bp, $node)); + } + + $li->add($leftAlign); + return $li; } diff --git a/library/Businessprocess/ServiceNode.php b/library/Businessprocess/ServiceNode.php index 6160bce..fc308f6 100644 --- a/library/Businessprocess/ServiceNode.php +++ b/library/Businessprocess/ServiceNode.php @@ -19,7 +19,12 @@ class ServiceNode extends MonitoredNode public function __construct($object) { - $this->name = $object->hostname . ';' . $object->service; + if (isset($object->statesOverride)) { + $this->name = $object->hostname . ';' . $object->service . ':' . $object->statesOverride; + $this->setStatesOverride($object->statesOverride); + } else { + $this->name = $object->hostname . ';' . $object->service; + } $this->hostname = $object->hostname; $this->service = $object->service; if (isset($object->state)) { @@ -67,6 +72,11 @@ 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 d317528..beea0af 100644 --- a/library/Businessprocess/State/MonitoringState.php +++ b/library/Businessprocess/State/MonitoringState.php @@ -122,24 +122,27 @@ class MonitoringState $key .= ';Hoststatus'; } - // We fetch more states than we need, so skip unknown ones - if (! $config->hasNode($key)) { - return; - } + $nodesNames = $config->getMatchingNodeNams($key); + foreach ($nodesNames as $nodeName) { + // We fetch more states than we need, so skip unknown ones + if (! $config->hasNode($nodeName)) { + return; + } - $node = $config->getNode($key); + $node = $config->getNode($nodeName); - 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 d4325cf..fcf382c 100644 --- a/library/Businessprocess/Storage/LegacyConfigParser.php +++ b/library/Businessprocess/Storage/LegacyConfigParser.php @@ -335,11 +335,17 @@ class LegacyConfigParser if ($bp->hasNode($val)) { $node->addChild($bp->getNode($val)); } else { - list($host, $service) = preg_split('~;~', $val, 2); - if ($service === 'Hoststatus') { - $node->addChild($bp->createHost($host)); + if (strpos($val, ':') !== false) { + list($host, $service, $statesOverride) = preg_split('~[;:]~', $val, 3); + $node->addChild($bp->createService($host, $service, $statesOverride)); } else { - $node->addChild($bp->createService($host, $service)); + list($host, $service) = preg_split('~;~', $val, 2); + + if ($service === 'Hoststatus') { + $node->addChild($bp->createHost($host)); + } else { + $node->addChild($bp->createService($host, $service)); + } } } } elseif ($val[0] === '@') { diff --git a/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php b/library/Businessprocess/Web/Form/Validator/NoDuplicateChildrenValidator.php index 9676de0..ecdd345 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->hasChild($value); + $found = $this->parent->hasMatchingChild($value); } if (! $found) { diff --git a/public/css/module.less b/public/css/module.less index 40d71f7..2da19a2 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -214,12 +214,12 @@ ul.bp { margin-right: .5em; } - > a.action-link { - margin-left: auto; // Let the first action link move everything to the right + a.action-link { + margin-left: 20px; + } - & + a.action-link { - margin-left: 0; // But really only the first one - } + > .left-side { + margin-left: auto; // Left alligned Icons } } @@ -260,13 +260,18 @@ ul.bp { } li.process > div > .state-ball, - li:not(.process) > .state-ball { + li:not(.process) > .state-ball, + div.left-side > .state-ball { border: .15em solid white; &.size-s { width: 7em/6em; height: 7em/6em; line-height: 7em/6em; + + &.last { + margin-right: 10px; + } } } } @@ -416,6 +421,14 @@ td > a > .badges { font-size: 0.5em; } + .state-ball { + position: absolute; + right: 0px; + bottom: 0px; + margin: 5px 5px 5px 5px; + border: 1px solid white; + } + > a { display: block; text-decoration: none; @@ -949,6 +962,39 @@ form dt label { } } +fieldset.collapsed { + dd, dt, ul, div { + display: none; + } + } + +fieldset { + margin-top: 15px; + padding: 0 0 1.5em 0; + border: none; + + 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; + } + + margin-bottom: 0.2em; + padding-bottom: 0; +} + form fieldset { min-width: 36em; } From 0c7fca926fe1256f61280c4fc8e08d9a6c58b9a6 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 26 Jun 2020 11:40:08 +0200 Subject: [PATCH 2/6] config: Use an extra line to store state overrides Storing overrides as part of a node's name leads to way too complicated code. A separate field is not only better for compatibility but also more straightforward to process. --- application/forms/AddNodeForm.php | 54 ++++--------- application/forms/EditNodeForm.php | 80 +++++-------------- .../views/helpers/FormStateOverrides.php | 40 ++++++++++ library/Businessprocess/BpConfig.php | 24 +----- library/Businessprocess/BpNode.php | 19 ----- .../Modification/NodeAddChildrenAction.php | 27 ++++--- library/Businessprocess/Node.php | 33 +++----- .../Businessprocess/Renderer/TreeRenderer.php | 4 +- library/Businessprocess/ServiceNode.php | 12 +-- .../Businessprocess/State/MonitoringState.php | 35 ++++---- .../Storage/LegacyConfigParser.php | 39 ++++++--- .../Storage/LegacyConfigRenderer.php | 22 +++++ .../Web/Form/Element/StateOverrides.php | 52 ++++++++++++ .../NoDuplicateChildrenValidator.php | 2 +- public/css/module.less | 44 ++++------ 15 files changed, 239 insertions(+), 248 deletions(-) create mode 100644 application/views/helpers/FormStateOverrides.php create mode 100644 library/Businessprocess/Web/Form/Element/StateOverrides.php 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 { From a8149a1983653f6b556ead35b9728924039dbb53 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 26 Jun 2020 14:11:40 +0200 Subject: [PATCH 3/6] ui: Use rule widget to show real state transformation instead Showing the override rules only in tree view but not in tile view is one problem. Another one however are rules for all states which then are difficult to decipher while not providing much benefit. The flash to indicate the real state also is not intuitive enough. That's why this change combines both widgets in a single one. This makes it more clear what the actual state is, what happened to it, and does not cobble the view with too much state balls. --- .../Renderer/TileRenderer/NodeTile.php | 1 + .../Businessprocess/Renderer/TreeRenderer.php | 58 +++++-------------- public/css/module.less | 33 ++++++----- 3 files changed, 33 insertions(+), 59 deletions(-) diff --git a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php index 7cb0c81..6e7d8f0 100644 --- a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php +++ b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php @@ -115,6 +115,7 @@ class NodeTile extends BaseHtmlElement if ($node instanceof ServiceNode && $node->getRealState() !== $node->getState()) { $this->add((new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ + 'class' => 'overridden-state', 'title' => sprintf( '%s', $node->getStateName($node->getRealState()) diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php index 3d58075..056cded 100644 --- a/library/Businessprocess/Renderer/TreeRenderer.php +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -136,43 +136,25 @@ class TreeRenderer extends Renderer return $icons; } - public function getNodeRealState(Node $node) + public function getOverriddenState(Node $node) { - $realState = []; - $realState[] = Html::tag('i', ['class' => 'icon icon-flash']); - $realState[] = (new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ + $overriddenState = Html::tag('div', ['class' => 'overridden-state']); + $overriddenState->add((new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ 'title' => sprintf( '%s', $node->getStateName($node->getRealState()) ) - ]); + ])); + $overriddenState->add(Html::tag('i', ['class' => 'icon icon-right-small'])); + $overriddenState->add((new StateBall(strtolower($node->getStateName())))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName() + ), + 'class' => 'last' + ])); - return $realState; - } - - public function getNodeStateOverride(Node $node) - { - $statesOverrights = []; - - $states = $node->getStateOverrides(); - foreach ($states as $originalState => $overrideState) { - $statesOverrights[] = (new StateBall(strtolower($node->getStateName($originalState))))->addAttributes([ - 'title' => sprintf( - '%s', - $node->getStateName($originalState) - ) - ]); - $statesOverrights[] = Html::tag('i', ['class' => 'icon icon-right-small']); - $statesOverrights[] = (new StateBall(strtolower($node->getStateName($overrideState))))->addAttributes([ - 'title' => sprintf( - '%s', - $node->getStateName($overrideState) - ), - 'class' => 'last' - ]); - } - - return $statesOverrights; + return $overriddenState; } /** @@ -283,23 +265,13 @@ class TreeRenderer extends Renderer $li->add($link); if ($node->getRealState() !== $node->getState()) { - $li->add($this->getNodeRealState($node)); - } - - $leftAlign = Html::tag('div', [ - 'class' => 'left-side', - ]); - - if (! empty($node->getStateOverrides())) { - $leftAlign->add($this->getNodeStateOverride($node)); + $li->add($this->getOverriddenState($node)); } if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) { - $leftAlign->add($this->getActionIcons($bp, $node)); + $li->add($this->getActionIcons($bp, $node)); } - $li->add($leftAlign); - return $li; } diff --git a/public/css/module.less b/public/css/module.less index 8d1dcf6..3db49bf 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -214,12 +214,17 @@ ul.bp { margin-right: .5em; } - a.action-link { - margin-left: 20px; + > :not(.overridden-state) + a.action-link { + margin-left: auto; // Let the first action link move everything to the right + + & + a.action-link { + margin-left: 0; // But really only the first one + } } - > .left-side { - margin-left: auto; // Left alligned Icons + .overridden-state { + margin-left: auto; + margin-right: 1em; } } @@ -260,18 +265,13 @@ ul.bp { } li.process > div > .state-ball, - li:not(.process) > .state-ball, - div.left-side > .state-ball { + li:not(.process) > .state-ball { border: .15em solid white; &.size-s { width: 7em/6em; height: 7em/6em; line-height: 7em/6em; - - &.last { - margin-right: 10px; - } } } } @@ -421,12 +421,13 @@ td > a > .badges { font-size: 0.5em; } - .state-ball { - position: absolute; - right: 0px; - bottom: 0px; - margin: 5px 5px 5px 5px; - border: 1px solid white; + .overridden-state { + font-size: .75em; + position: absolute; + left: 0; + bottom: 0; + margin: .5em; + border: 1px solid white; } > a { From 49ebbc4cdb1673ded9f8990b745735c36c518611 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 30 Jun 2020 16:07:47 +0200 Subject: [PATCH 4/6] Apply state overrides on demand instead of directly Internally non-process children are only instantiated once. This means when applying state overrides directly they're used everywhere and do not differ between the containing process. State overrides are now applied explicitly and on demand, decoupling them from children. --- application/clicommands/ProcessCommand.php | 14 ++-- application/forms/AddNodeForm.php | 17 ++--- application/forms/EditNodeForm.php | 24 ++++--- library/Businessprocess/BpNode.php | 64 +++++++++++++++++-- .../Modification/NodeAddChildrenAction.php | 18 +----- library/Businessprocess/Node.php | 38 ++--------- library/Businessprocess/Renderer/Renderer.php | 6 +- .../Renderer/TileRenderer/NodeTile.php | 8 ++- .../Businessprocess/Renderer/TreeRenderer.php | 33 +++++----- .../Storage/LegacyConfigParser.php | 2 +- .../Storage/LegacyConfigRenderer.php | 6 +- .../Web/Form/Element/StateOverrides.php | 9 ++- 12 files changed, 133 insertions(+), 106 deletions(-) diff --git a/application/clicommands/ProcessCommand.php b/application/clicommands/ProcessCommand.php index af3cc29..0d00a37 100644 --- a/application/clicommands/ProcessCommand.php +++ b/application/clicommands/ProcessCommand.php @@ -167,21 +167,22 @@ class ProcessCommand extends Command } } - protected function renderProblemTree($tree, $useColors = false, $depth = 0) + protected function renderProblemTree($tree, $useColors = false, $depth = 0, BpNode $parent = null) { $output = ''; foreach ($tree as $name => $subtree) { /** @var Node $node */ $node = $subtree['node']; + $state = $parent !== null ? $parent->getChildState($node) : $node->getState(); if ($node instanceof HostNode) { - $colors = $this->hostColors[$node->getState()]; + $colors = $this->hostColors[$state]; } else { - $colors = $this->serviceColors[$node->getState()]; + $colors = $this->serviceColors[$state]; } - $state = sprintf('[%s]', $node->getStateName()); + $state = sprintf('[%s]', $node->getStateName($state)); if ($useColors) { $state = $this->screen->colorize($state, $colors[0], $colors[1]); } @@ -193,7 +194,10 @@ class ProcessCommand extends Command $state, $node->getAlias() ); - $output .= $this->renderProblemTree($subtree['children'], $useColors, $depth + 1); + + if ($node instanceof BpNode) { + $output .= $this->renderProblemTree($subtree['children'], $useColors, $depth + 1, $node); + } } return $output; diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php index a01aee2..11f24f3 100644 --- a/application/forms/AddNodeForm.php +++ b/application/forms/AddNodeForm.php @@ -502,16 +502,17 @@ class AddNodeForm extends QuickForm $changes = ProcessChanges::construct($this->bp, $this->session); switch ($this->getValue('node_type')) { case 'service': - $properties = $this->getValues(); - unset($properties['children']); + $stateOverrides = $this->getValue('stateOverrides'); + if (! empty($stateOverrides)) { + $services = []; + foreach ($this->getValue('children') as $service) { + $services[$service] = $stateOverrides; + } - $services = []; - foreach ($this->getValue('children') as $service) { - $services[$service] = $properties; + $changes->modifyNode($this->parent, [ + 'stateOverrides' => array_merge($this->parent->getStateOverrides(), $services) + ]); } - - $changes->addChildrenToNode($services, $this->parent); - break; case 'host': case 'process': if ($this->hasParentNode()) { diff --git a/application/forms/EditNodeForm.php b/application/forms/EditNodeForm.php index 2d60d88..98596e5 100644 --- a/application/forms/EditNodeForm.php +++ b/application/forms/EditNodeForm.php @@ -156,7 +156,6 @@ class EditNodeForm extends QuickForm if ($this->hasParentNode()) { $this->addElement('hidden', 'node_type', [ 'disabled' => true, - 'ignore' => true, 'decorators' => ['ViewHelper'], 'value' => $monitoredNodeType ]); @@ -192,7 +191,7 @@ class EditNodeForm extends QuickForm if ($this->getSentValue('hosts') === null) { $this->addServicesElement($this->host); $this->addServiceOverrideCheckbox(); - if (! empty($this->node->getStateOverrides()) || $this->getSentValue('service_override') === '1') { + if ($this->getElement('service_override')->isChecked() || $this->getSentValue('service_override') === '1') { $this->addServiceOverrideElement(); } } elseif ($host = $this->getSentValue('hosts')) { @@ -236,7 +235,7 @@ class EditNodeForm extends QuickForm $this->addElement('checkbox', 'service_override', [ 'ignore' => true, 'class' => 'autosubmit', - 'value' => ! empty($this->node->getStateOverrides()), + 'value' => ! empty($this->parent->getStateOverrides($this->node->getName())), 'label' => $this->translate('Override Service State'), 'description' => $this->translate('Enable service state overrides') ]); @@ -247,7 +246,7 @@ class EditNodeForm extends QuickForm $this->addElement('stateOverrides', 'stateOverrides', [ 'required' => true, 'states' => $this->enumServiceStateList(), - 'value' => $this->node->getStateOverrides(), + 'value' => $this->parent->getStateOverrides($this->node->getName()), 'label' => $this->translate('State Overrides') ]); } @@ -449,11 +448,18 @@ class EditNodeForm extends QuickForm switch ($this->getValue('node_type')) { case 'service': - $properties = $this->getValues(); - unset($properties['children']); - $services = [$this->getValue('children') => $properties]; - $changes->addChildrenToNode($services, $this->parent); - break; + $stateOverrides = $this->getValue('stateOverrides') ?: []; + if (! empty($stateOverrides)) { + $stateOverrides = array_merge( + $this->parent->getStateOverrides(), + [$this->getValue('children') => $stateOverrides] + ); + } else { + $stateOverrides = $this->parent->getStateOverrides(); + unset($stateOverrides[$this->getValue('children')]); + } + + $changes->modifyNode($this->parent, ['stateOverrides' => $stateOverrides]); case 'host': case 'process': $changes->addChildrenToNode($this->getValue('children'), $this->parent); diff --git a/library/Businessprocess/BpNode.php b/library/Businessprocess/BpNode.php index 9aeaab8..58a7c11 100644 --- a/library/Businessprocess/BpNode.php +++ b/library/Businessprocess/BpNode.php @@ -26,6 +26,7 @@ class BpNode extends Node protected $missing = null; protected $empty = null; protected $missingChildren; + protected $stateOverrides = []; protected static $emptyStateSummary = array( 'OK' => 0, @@ -71,7 +72,7 @@ class BpNode extends Node } elseif ($child->isMissing()) { $this->counters['MISSING']++; } else { - $state = $child->getStateName(); + $state = $child->getStateName($this->getChildState($child)); $this->counters[$state]++; } } @@ -127,9 +128,13 @@ class BpNode extends Node $problems = array(); foreach ($this->getChildren() as $child) { - if ($child->isProblem() - || ($child instanceof BpNode && $child->hasProblems()) - ) { + if (isset($this->stateOverrides[$child->getName()])) { + $problem = $this->getChildState($child) > 0; + } else { + $problem = $child->isProblem() || ($child instanceof BpNode && $child->hasProblems()); + } + + if ($problem) { $problems[] = $child; } } @@ -187,7 +192,8 @@ class BpNode extends Node if ($nodeState !== 0) { foreach ($this->getChildren() as $child) { - $childState = $rootCause ? $child->getSortingState() : $child->getState(); + $childState = $this->getChildState($child); + $childState = $rootCause ? $child->getSortingState($childState) : $childState; if (($rootCause ? $this->getSortingState() : $nodeState) === $childState) { $name = $child->getName(); $tree[$name] = [ @@ -327,6 +333,31 @@ class BpNode extends Node return $this->info_command; } + public function setStateOverrides(array $overrides, $name = null) + { + if ($name === null) { + $this->stateOverrides = $overrides; + } else { + $this->stateOverrides[$name] = $overrides; + } + + return $this; + } + + public function getStateOverrides($name = null) + { + $overrides = null; + if ($name !== null) { + if (isset($this->stateOverrides[$name])) { + $overrides = $this->stateOverrides[$name]; + } + } else { + $overrides = $this->stateOverrides; + } + + return $overrides; + } + public function getAlias() { return $this->alias ? preg_replace('~_~', ' ', $this->alias) : $this->name; @@ -354,6 +385,27 @@ class BpNode extends Node return $this->state; } + /** + * Get the given child's state, possibly adjusted by override rules + * + * @param Node|string $child + * @return int + */ + public function getChildState($child) + { + if (! $child instanceof Node) { + $child = $this->getChildByName($child); + } + + $childName = $child->getName(); + $childState = $child->getState(); + if (! isset($this->stateOverrides[$childName][$childState])) { + return $childState; + } + + return $this->stateOverrides[$childName][$childState]; + } + public function getHtmlId() { return 'businessprocess-' . preg_replace('/[\r\n\t\s]/', '_', $this->getName()); @@ -391,7 +443,7 @@ class BpNode extends Node $child->setMissing(); } - $sort_states[] = $child->getSortingState(); + $sort_states[] = $child->getSortingState($this->getChildState($child)); $lastStateChange = max($lastStateChange, $child->getLastStateChange()); $bp->endLoopDetection($this->name); } diff --git a/library/Businessprocess/Modification/NodeAddChildrenAction.php b/library/Businessprocess/Modification/NodeAddChildrenAction.php index 8f9c5e0..5d5ab29 100644 --- a/library/Businessprocess/Modification/NodeAddChildrenAction.php +++ b/library/Businessprocess/Modification/NodeAddChildrenAction.php @@ -31,27 +31,15 @@ class NodeAddChildrenAction extends NodeAction { $node = $config->getBpNode($this->getNodeName()); - foreach ($this->children as $name => $properties) { - if (is_int($name)) { - // TODO: This may be removed once host nodes also have properties - $name = $properties; - } - + foreach ($this->children as $name) { if (! $config->hasNode($name) || $config->getNode($name)->getBpConfig()->getName() !== $config->getName()) { if (strpos($name, ';') !== false) { list($host, $service) = preg_split('/;/', $name, 2); if ($service === 'Hoststatus') { - $child = $config->createHost($host); + $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); - } + $config->createService($host, $service); } } elseif ($name[0] === '@' && strpos($name, ':') !== false) { list($configName, $nodeName) = preg_split('~:\s*~', substr($name, 1), 2); diff --git a/library/Businessprocess/Node.php b/library/Businessprocess/Node.php index bec3346..f22339b 100644 --- a/library/Businessprocess/Node.php +++ b/library/Businessprocess/Node.php @@ -46,8 +46,6 @@ abstract class Node self::NODE_EMPTY => 0 ); - protected $stateOverrides = []; - /** @var string Alias of the node */ protected $alias; @@ -199,18 +197,6 @@ abstract class Node return $this; } - public function setStateOverrides(array $overrides) - { - $this->stateOverrides = $overrides; - - return $this; - } - - public function getStateOverrides() - { - return $this->stateOverrides; - } - /** * Forget my state * @@ -260,30 +246,14 @@ abstract class Node ); } - if (isset($this->stateOverrides[$this->state])) { - return $this->stateOverrides[$this->state]; - } else { - return $this->state; - } - } - - public function getRealState() - { - if ($this->state === null) { - throw new ProgrammingError( - sprintf( - 'Node %s is unable to retrieve it\'s state', - $this->name - ) - ); - } - return $this->state; } - public function getSortingState() + public function getSortingState($state = null) { - $state = $this->getState(); + if ($state === null) { + $state = $this->getState(); + } if (self::$ackIsOk && $this->isAcknowledged()) { $state = self::ICINGA_OK; diff --git a/library/Businessprocess/Renderer/Renderer.php b/library/Businessprocess/Renderer/Renderer.php index 4c9a8de..35e3225 100644 --- a/library/Businessprocess/Renderer/Renderer.php +++ b/library/Businessprocess/Renderer/Renderer.php @@ -180,9 +180,9 @@ abstract class Renderer extends HtmlDocument if ($node->isEmpty() && ! $node instanceof MonitoredNode) { $classes = array('empty'); } else { - $classes = array( - strtolower($node->getStateName()) - ); + $classes = [strtolower($node->getStateName( + $this->parent !== null ? $this->parent->getChildState($node) : null + ))]; } if ($node->hasMissingChildren()) { $classes[] = 'missing-children'; diff --git a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php index 6e7d8f0..ef26693 100644 --- a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php +++ b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php @@ -113,12 +113,14 @@ class NodeTile extends BaseHtmlElement )); } - if ($node instanceof ServiceNode && $node->getRealState() !== $node->getState()) { - $this->add((new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ + if ($this->renderer->rendersSubNode() + && $this->renderer->getParentNode()->getChildState($node) !== $node->getState() + ) { + $this->add((new StateBall(strtolower($node->getStateName())))->addAttributes([ 'class' => 'overridden-state', 'title' => sprintf( '%s', - $node->getStateName($node->getRealState()) + $node->getStateName() ) ])); } diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php index 056cded..efe8d77 100644 --- a/library/Businessprocess/Renderer/TreeRenderer.php +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -79,7 +79,7 @@ class TreeRenderer extends Renderer if ($node instanceof BpNode) { $html[] = $this->renderNode($bp, $node); } else { - $html[] = $this->renderChild($bp, $node); + $html[] = $this->renderChild($bp, $this->parent, $node); } } @@ -106,9 +106,10 @@ class TreeRenderer extends Renderer /** * @param Node $node * @param array $path + * @param BpNode $parent * @return BaseHtmlElement[] */ - public function getNodeIcons(Node $node, array $path = null) + public function getNodeIcons(Node $node, array $path = null, BpNode $parent = null) { $icons = []; if (empty($path) && $node instanceof BpNode) { @@ -116,7 +117,7 @@ class TreeRenderer extends Renderer } else { $icons[] = $node->getIcon(); } - $state = strtolower($node->getStateName()); + $state = strtolower($node->getStateName($parent !== null ? $parent->getChildState($node) : null)); if ($node->isHandled()) { $state = $state . '-handled'; } @@ -136,20 +137,20 @@ class TreeRenderer extends Renderer return $icons; } - public function getOverriddenState(Node $node) + public function getOverriddenState($fakeState, Node $node) { $overriddenState = Html::tag('div', ['class' => 'overridden-state']); - $overriddenState->add((new StateBall(strtolower($node->getStateName($node->getRealState()))))->addAttributes([ - 'title' => sprintf( - '%s', - $node->getStateName($node->getRealState()) - ) - ])); - $overriddenState->add(Html::tag('i', ['class' => 'icon icon-right-small'])); $overriddenState->add((new StateBall(strtolower($node->getStateName())))->addAttributes([ 'title' => sprintf( '%s', $node->getStateName() + ) + ])); + $overriddenState->add(Html::tag('i', ['class' => 'icon icon-right-small'])); + $overriddenState->add((new StateBall(strtolower($node->getStateName($fakeState))))->addAttributes([ + 'title' => sprintf( + '%s', + $node->getStateName($fakeState) ), 'class' => 'last' ])); @@ -243,14 +244,14 @@ class TreeRenderer extends Renderer if ($child instanceof BpNode) { $ul->add($this->renderNode($bp, $child, $path)); } else { - $ul->add($this->renderChild($bp, $child, $path)); + $ul->add($this->renderChild($bp, $node, $child, $path)); } } return $li; } - protected function renderChild($bp, Node $node, $path = null) + protected function renderChild($bp, BpNode $parent, Node $node, $path = null) { $li = Html::tag('li', [ 'class' => 'movable', @@ -258,14 +259,14 @@ class TreeRenderer extends Renderer 'data-node-name' => $node->getName() ]); - $li->add($this->getNodeIcons($node, $path)); + $li->add($this->getNodeIcons($node, $path, $parent)); $link = $node->getLink(); $link->getAttributes()->set('data-base-target', '_next'); $li->add($link); - if ($node->getRealState() !== $node->getState()) { - $li->add($this->getOverriddenState($node)); + if (($overriddenState = $parent->getChildState($node)) !== $node->getState()) { + $li->add($this->getOverriddenState($overriddenState, $node)); } if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) { diff --git a/library/Businessprocess/Storage/LegacyConfigParser.php b/library/Businessprocess/Storage/LegacyConfigParser.php index 1afc256..4142731 100644 --- a/library/Businessprocess/Storage/LegacyConfigParser.php +++ b/library/Businessprocess/Storage/LegacyConfigParser.php @@ -247,7 +247,7 @@ class LegacyConfigParser $stateOverrides[(int) $from] = (int) $to; } - $node->getChildByName($childName)->setStateOverrides($stateOverrides); + $node->setStateOverrides($stateOverrides, $childName); } } diff --git a/library/Businessprocess/Storage/LegacyConfigRenderer.php b/library/Businessprocess/Storage/LegacyConfigRenderer.php index eba26bc..ebe9589 100644 --- a/library/Businessprocess/Storage/LegacyConfigRenderer.php +++ b/library/Businessprocess/Storage/LegacyConfigRenderer.php @@ -218,14 +218,14 @@ class LegacyConfigRenderer public static function renderStateOverrides(BpNode $node) { $stateOverrides = ''; - foreach ($node->getChildren() as $child) { + foreach ($node->getStateOverrides() as $childName => $overrideRules) { $overrides = []; - foreach ($child->getStateOverrides() as $from => $to) { + foreach ($overrideRules as $from => $to) { $overrides[] = sprintf('%d-%d', $from, $to); } if (! empty($overrides)) { - $stateOverrides .= '!' . $child->getName() . '|' . join(',', $overrides); + $stateOverrides .= '!' . $childName . '|' . join(',', $overrides); } } diff --git a/library/Businessprocess/Web/Form/Element/StateOverrides.php b/library/Businessprocess/Web/Form/Element/StateOverrides.php index 49cb233..c2216c0 100644 --- a/library/Businessprocess/Web/Form/Element/StateOverrides.php +++ b/library/Businessprocess/Web/Form/Element/StateOverrides.php @@ -41,9 +41,12 @@ class StateOverrides extends FormElement public function setValue($value) { $cleanedValue = []; - foreach ($value as $from => $to) { - if ((int) $from !== (int) $to) { - $cleanedValue[$from] = $to; + + if (! empty($value)) { + foreach ($value as $from => $to) { + if ((int) $from !== (int) $to) { + $cleanedValue[$from] = $to; + } } } From ec54b6df5790d72ae9f3fa9cbeba8541392040c9 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 30 Jun 2020 16:48:18 +0200 Subject: [PATCH 5/6] doc: Add chapter for state overrides --- doc/07-State-Overrides.md | 45 ++++++++++++++++++ .../0701_override_config.png | Bin 0 -> 76256 bytes .../0702_overridden_tile.png | Bin 0 -> 36046 bytes .../0703_overridden_tree.png | Bin 0 -> 40178 bytes 4 files changed, 45 insertions(+) create mode 100644 doc/07-State-Overrides.md create mode 100644 doc/screenshot/07_state_overrides/0701_override_config.png create mode 100644 doc/screenshot/07_state_overrides/0702_overridden_tile.png create mode 100644 doc/screenshot/07_state_overrides/0703_overridden_tree.png diff --git a/doc/07-State-Overrides.md b/doc/07-State-Overrides.md new file mode 100644 index 0000000..0905346 --- /dev/null +++ b/doc/07-State-Overrides.md @@ -0,0 +1,45 @@ +# State Overrides + +Business processes utilize their children's states to calculate their own state. +While you can influence this with [operators](09-Operators.md), it's also possible +to override individual states. (Currently this applies only to service nodes.) + +## Configuring Overrides + +State overrides get configured per node. When adding or editing a node, you can +define which state should be overridden with another one. + +Below `WARNING` is chosen as a replacement for `CRITICAL`. + +![Service State Override Configuration](screenshot/07_state_overrides/0701_override_config.png "Service State Override Configuration") + +## Identifying Overrides + +In tile view overridden states are indicated by an additional state ball in the +lower left of a tile. This is then the actual state the object is in. + +![Overridden Tile State](screenshot/07_state_overrides/0702_overridden_tile.png "Overridden Tile State") + +In tree view overridden states are indicated on the very right of a row. There +the actual state is shown and which one it is replaced with. + +![Overridden Tree State](screenshot/07_state_overrides/0703_overridden_tree.png "Overridden Tree State") + +## File Format Extensions + +The configuration file format has slightly been changed to accommodate state +overrides. Though, previous configurations are perfectly upwards compatible. + +### New Extra Line + +For process nodes a new extra line is used to store state overrides. + +``` +state_overrides dev_database_servers!mysql;mysql|2-1 +``` + +The full syntax for this is as follows: + +``` +state_overrides !|n-n[!|n-n[,n-n]] +``` diff --git a/doc/screenshot/07_state_overrides/0701_override_config.png b/doc/screenshot/07_state_overrides/0701_override_config.png new file mode 100644 index 0000000000000000000000000000000000000000..49ca2ad33ad1bfb446f4a7ec6612a8d2699a6819 GIT binary patch literal 76256 zcmYg$1CVDs6Ytob9ox3GW81cE+qP}(Xvel~+n)azJ9>NX{oborr%virC!Owee(7{N zCsIL993BQ61_%fUUQ$9t2?z*O7YGQ%9}40xCD@{U1qg^h-b+QpMaj^e(80;x%+kh` z(8bfil+e_}(hLa5W1}Wp(+Rgd&Gwrq3LE5)8K=dx6@>k3Gdr&kF_lv0%Z7BB2=&=M zLXH^+(7@IAOYi6h;(|(?$8JEZ53z zJ}<+0(kZj{pNDN%J^9|4Ww~>PP=lb*E~3 zs+ee$;daZW>zr4Odsw7h+j;o>`E%POV%}c=_2%<&zei2@ZhE$WSJb!tP};&UREoZQ zH;i>;&p&o}`?Te~>zrC%FHXAq&@8U?xFc!sunAZxxBYM zDx~dULc0Ul&%b-Yp8p4WsT9N_yt8T0cHAjCN&9Xynq3~~Dp?Od-I0uD9S#z4UM^+~ ztVy34M$+UAIw0D4s6MG+X3RIjF9A3`Ngr-u5oif~q7#X`-^kN=ce89M^e*E1fpsk}O3-X}mN=OY59%Nke(Mc}YwA zdb$+|qAX3@vblMslOq?>^=7%f=V9WOB!+WgtT={y<1G0;)3GemJkzyhJzd`r7?q~3 z;lirQ-ke>c{!oqw&~RzjNnmvyf-2AbmZB`r^Qpd~r}=q!$v>9mZ92UxbKY@JW8GyX z<+(cmEtljZHsa%A(nSgSqe*?n#+Av-RF120dhy3N%UH=)#&HUh5@zeed7FOwdv3db zDo64~??m=@`4m>^&A0doT;)59{jP~^Hu42WXF+fnYui7a2N636Uw zvioU=8rhGJoB_$sjl&biW0}^dr?($5u^^SD;3FmS#xSimvav{+`B7E9mGm03h0dS` zGsAT}B?@L_Th9ULCw5#a#EaO00JkSWAMn0`SBQxhz~?iKiw=4N zSxe27+W?DZCriptLINFs8LC%dZBt-ls%4qDsrm3bszupn;-<6)a53Hmdm+tN zQ=X?*`=VswiliYXwN-2FaT(eEKXaih9Kck^b>mg@hD{Nd;eC`t4ceLtFmy2grlH@hw8&``pSt zTzb9_3Q6HvE7SvgU-jMLk63^1Pc;02JFqh}{Gh?hfDTC5hH^bBk)E^3+jhq3PUdgQ zDW)&({)gIFb(NTlXFN>5{_7-PQ~j-bvUjiHH;UqXn!YY#r-$!VDnIy{(<{^~{q^$E z-q~KWtOTGr^fqP>+FTFC^Ev{zmv6ox+tW!7c`{7z_&=(qo7*FGiR%T|
    *o~OL)-{oJGFd5FR#yKp~|}9RDCOXDM6aAm}8!j+eM0n zrcJoO7!$^xIcbMKQX4@+O>d-woGgK!1ebUfcwz@v1u&aG&3&o+d0cpvB4oc)vWF~) z3aeQ8+P|pwRK@N-0)<-Bo3Nau=i(KTOz9Wy2JfeM>w(gSQ!ns4F`r4X*g_^!l?UgS z|A6i_wRe|fNGkF`g*(`J7}C3t2no)r!!N%_wkH$XEYvq0i2>dWD=!8_dnREl!vQcp zpk84alnQ2AQ_>+Q4UsoPd&ZQtfwd{xEl}5Zu}VB1L34wLjg~o^+q90b?np7qv~$ns z12`cga$F;u<)@8=YegTdvZv%55cUC<_|66XQ!SN> z6mAthxV3@Uni`A+-P1!ySQW%E6l$L&9T{3-E9ZS(2tANGA}-j!z#*Z}Q#{O0QZ1VU z4mbPS=S3~SZbKGQ;R;;@&~<-RFB0Z)G9gT*3!Vg80yoi2#?Gx2SwURzyT>2W4>MHL zJ^?4G@V5PG`_)OosD9oN6h^`Z@i^7Q6YED2_EUrqIuwgnMn_S?Qa^+^N#pP)=OUS? zU8DolD8_0TJ6k&iQ>Y_Erz;;RtuJsi$>jj)`X@AnZ|&DM&KF!pMA05a)U4l2 zu36ZA=qroCm{^X5D4c&q=^TDGHd7yJvYUrAB7jaXNC4BF^UOgXWx}v6R6r^M5R`n) z1<}RaINlOHc(a6l=1VX2fOPW--v9fkI!kXcaP>@$6&cTlPU;f4}}I7(=Q zCh|i&D3!wG;tbnzN03ilu@)o7icrKY@jaNObR-$7(nLP2vb^lrR+T3O9)KbaA8B*y zrJTFHfhRG!zr3SPud<4?N|Fn}$ALLu-cM)Kk;5q*bln++X zoKCcVpFT)s(da_ZsZEz1O#+xAo`v`_i)n589mzdktKklxj)9}6V;9uyCL|j+vPf23 zI#vg2%pi#5Og4AknrYD@BT(7#*{@~lrTeG>%%!9&@TLV^9-aFQK10v&XB?~L-LKe_ z`mQoMgGiK-&G;V`bR#;V1KZ-;9q~O_e;!#G28_v4OdiL7DR)D_;rBN!(pm`e2AV+R zk;slri6jsMRb(2;wd~aZMUF`rB?IBmaP1@?d5;1yV6$H;S_j_{xlyG@dWvd}jS$Bv zU?lJK>$|?vwV&$>0aF#6_>q#M5VStObz5Hl`Xei@!fn+T-Fz-Ws*XX;W zEN`#faaVB3BP2)-)dw}a=(>E&cvZt@i>$t9C1G*EH!8oYN|^U1!(hNk06JK6lAbT* zIOh_+InaW0pbOs;e<-5HygBl0G7hjb<&BPJ0~LP_tmutEIMimHC;^|nh2Rp4sWi#J z8{bGV6(@i!gBdIYuYtur{iJdI9_*dw*S)p>w)N{O2)^Wl{h53@SMhO?wZl^b%2|`5 z6o$sccE*e$V`G8wTOXU74|@Z+V_`1-Sis}uliipSC6j4Q_(zNyP!oqrt*b=*y8>gK zG&jJ#d&e2C1pvm(A~gpDTw}UOORNvV_NRUfE{k*n@_UTb1X$k1p}q(UsqKtf2L>G) zjS>yoh|wFCQBEgNRNn$nL<&~Tq48Mu1f0!+K6M=1P9QVU5{4IeINI>lbTki^trlvA z+ku4|!772A3_(MtFRR8jYGb-s!+@+u2mH{mNx!Aqp> zWeZ|4Io0n+eY7M_s(ueexN;y02RGkwCv~RfPdYoCngC+T=BUs|n23X>L7;3>MQRUr z3zzGAQ?dxBpHVNoGz&pDIrcx|3)wFtHsL~ zjO_2Ti(Va@uP$!i!Od{6{wawflxD_A2uZS1i4Q}45hqrjes`zFzPRBtldVRGLkeCR z%@hxc`eMWYkZjYHKTC1!YyC(pgjqsWBPb+b7Pi~(v3fF^E|G9T8?*{8q}Lb*?3G3# zsH{6UDxMhByRn?KdZc);Hi0?f*wA`}iLZ=x+la?MYL?YvK-pRv&|s7Rtf<)J zgiPeD(IISd@1`iBl=gJRAVCQpv~3qKC`z6RI)ZGRQ(UgWNj6{{bI$1cX(GE_yIDX= zpg&)!bq+FqC5GsTT#*DIKu8fI-(;jDiohX1GjS3R^Ui2(!bEUbiM+3#MUhhRqR0|S z2NjmV6n5l{mtq%3XYiLacFx}<=!PZwvJwuL?4DVdg}N4c0JoHdx+9S)ep;H7Vz33# z1);qa77z)Cu@{31LWy1oZ^`5ANkhW5G5(|n)zygxY#^(HtkRouS(je`;~7FCWUrt+ zY#~FS62p;}e7#=q_g1izZ}j%!d=l16zq$IjBJz+#CH`7Yx_2~>gAzVo{5<$YXHnje z0Ckq5-0UqH1&1wwVq%RG^W_gsQnZXrdB!6Db6yMmcS|;qY+*p-J&i?37V_9e(>laZ z9Q-g=Sg{Z`ZhSukUKCQOp+rTn0G{VZHNeU?>tY;lJq++{S|c@|MNKk?&=!xfPPx8> zas#5y6m=V^VtT!P2?o*#)(iU!$uRa4PsrOMHtCLh0f7>Q*G=T2E&!F#v5(mpKkF>v z?YC|;Z`)@z29siyvM3G6X_B{&y^Gth=u}>{Tx~HZl@{In0`8u7dUnTEPytl`pvoS+ zNa-`qB;azY6{7=1*KR`^cIh!nB=n%E{?`WvoyZz}Aq1h-4hNQ3@mxC2nrQqF3p}}r z4d_C_=8Uj((u;oOBSw#~8V3#WY$QVeTN&`xACMkRfglWvPDkD%zmcfz%T^PWJ*XbZ zsAq_}EN(+zTqKke`Hh94)W;BgLu#S6#F&i&Vq~M8;e^?w3o0S$_<^U#cx(jHfMPZh zgyK7b{T3Qz&#?@G{b%c;S9`|kCK$FaI+h1Ff zmb;EoN!f+>TP30190D~J&xu5eUl7F9 ztRX2xAMy*ZbK9{>H6;~~MgoDkXZv)I74b=B2!lwhNU9%+J|~UvzvhJ^j8uV_wWQ>T z+1T*~f#$XCd$l66^cXsu6FTU=EYA*-gi@;YMlNxDU3Ll!OYEyN{62%@F;#!O;?pL z^pMdUXhV^jWW+7CEQ5ke8dxxp^z+`}YCMrZg0>$ST%eFaLhN3{FfAj6k)v5r0fji6QLX>Ym zMVJ%6|6n>8_=$wEm@n|T-?djkvv6t@FB2HW4Z2&sz z;nvpqoKn2l10|8IE9bN$HK3uD&s$`?1ziB4p}H<^CrM)g;J4Iuvb?Ju5(u{_^}tWY z`*3Ue;f{pS?K+*Baj+Jb>ptieJ{hWlxyJ&{+*)Q^kp;z8E(%{@1&pUtCg;*bMv&Ij z80lg2i2gITEs@*4|AYuMofoRcc0B5j;3XmB?Iah`8UgK@G$B~(?n%lcpH9Gb|2TtxbLT#%IDhfuvI-itO#x3vVaaq&ni z6*wTAv7_!S-bf5uu|rk&>V&?2Zy@+@HXUK#+Oop5kk+f`k_kzu8n_iMCWL5phgc?RDHuSd zqGX*_Nkq%iwVc0_V8FT{e;@@^+nQLN5w}T5 zTU0TYf{fge8qgK;oA)J|)G4Q+%CniG^G;YgWd5)pRS2|-0IR{*HyZ|L8YyM#DUBuI zY5~QQposJHcq;&na)U_>s&O}3=bch?Euj<@zU-s}gTP*(le?9G_(+i5dw<<}x#2~q zlK~ZS3+S(QeBVsgkZ|whw{VYVY7w#=PG(KnBvtlOGYp#U~#8<7W-#FQ{dEtJSYsPs-(IL0SB`I5DLB+2@c1(wyWz*wN^Mqv4r86kP zVQplljaPOa>u&zOsZB+F)vv~Ln^@tNxj5Fd0zzYMyyg3_&RaWv{_YuaZ$_Ngd+ABg z0-U~A;7A?EF(zNbLiDGsYne3YGr;k z3iC}rP#HzV4eqTvD1HMckHgm%?^q~^#LBpV^8c!WgQ)J8#wG8lCYSAiLkohk-*7~1 zV5HVOAg&<|kk24kj)x4+nfl$UXH9%!V6#+t##KewoFSh`_bRiX>3}^K*Z!bzFiiNU z2cp<4%1<}gpQ*7=g#e)es_5CDeM<{rVmpy|ElT5AX$g^P^4z?G|9*+HpM>XG`|4Bp zwyNG!C(xb%f*0~7!a@F%1}cy{*uR;)ijKlbdaL=i?It8i{)JV;Ie?j7%n0f1`V9Os znO?k}XgPQVv5oS9gIY4*Hee!9omzlhUz}HXHi%%V1LXo}s+zA5E>HfdNw9sQB8ZKQ z>$;|ZNz3uc4w>i)oy94tMm)!QyQ(Tp(3RZX6-x`LH$i4v%RS1)_Lp$<4mWjBH66Ed ziz5`3f)&E(;NKls_xGy+2@9Hf1~cX~7;>@dC(H$5Yr(Nn&qHgw=X1OT{LevT< zTD?Me$Kpt(?!^=WH!kvZzbS`DmRt25zMEjfy#ok7)`A#^l`G6;Bw3kO6}wZenQ)Em z8iR3VPRo`|Kigy3F2>t#XId3YFE%S3tK1wr#L%)^FAf&W_<|j->(7ihiaI~-!95~F zOUx~OgA|Kyw$-37tH2SG@f5#DRNF#Z62;C0cK#wENIN8nZC2>HM22epXT*F{O0_(1N!{kDOr|0fc?_EW0aQ&Nc zyy^0K6TG7x!NERo*Py+AwI85YwRWks?u&On!G1)L>AAs`wA;Ddn&$dQA_7u6)kwUB zgWzg1MaF=}H334HOXJ1}%wp!w0g6*FN<>zdn8<=O)_}cTzDpD$`niA&ZyU zr19=|w3ONiT*tpy&ODJzg_ zk_1Mu(iD*nu{zaAn4KXdsJsZWg`+ofX`|2+Gd6}|^XcM<%3v1oa%Y-1%#4S9a-Tg- z>=XmtJg+D-ysQG4AK;M|4S(46MEMD?$to=yS!5-6SAXHUJ-p0GzWu3MWe|9v}12oR{DAEFv~EE^>X@&36nz3|D0 z7_~}zrUDJ0_MBQy)(o7@{L1{OZ;8R|_@Zj=e1md`l_@1I9CiS{3@$N4=ol_Lu?@Kp z$?cPe-pHZ$=SgB&1i8pUv`v0>6`jqwxZ`$)V!O6HfyKzAz!51Ln6ux|@CqN?4q4ts zcZJH!q(y(T5Tww?ymNg8&GvGmfDQ5wv`W=065d&jbUBCv8X+((1&qC)MK~nQLX!o5qe{ZjteIZYsx--D9DIaDBH4=$Yd-!^!~hBRKyg8YvO7l>Jp4;0hz&i_0~M? z?WF5`DiUF#gBR056bBH=qfrJYp9#DZk%g!);#!%tfAfFBtc{CAFGI{uA3mZd)Pg|SM70ITYXVA~+T zWre{b3k<#hv4HTagUFS8U=asA`LVG1goYgn7OklSJ-RiM;v&Uc44Mf~>atUpR;I14mHJd?mpg_u^Ul zGoad;?m4UG;_rl`J!6IDf~#B;(mX9l-Cq=Cakw%j@<&>Ah-@Jp&8|?uMN_UREX5mG zX9>4>O85ND4=cYC<)RkkWVFPWrVo88dQ9YP?aqeg7Yc(!jYfUIc;Ob3yZK3Sdp_;< zqI@kq`&^zz(edG4>Q*u95J5s6+3sF^%Qflskr4lsXswvVv;^M;21uCL}Ia(T^T(g+I+;C znFAy}&O=%jAqYRLogSjgL0u`wN<59f9e6Ke(>pEF~sgOeXV3TS^q!_qD6vM6cuu+2+B>@K(5|M`eu zzdm4>6)T-AK7R}m#?DJhTMfq@6ytu5;g03*y6AjNMu<7r30aA6n5mLW=*YKuOvK#r zi1%zd%@}+J`^hfx_^Aoh<&287Y-lY*QxnLD~J?@BwqL!M(lHoFGX^U-td8 zpsqNK%jDX2PQ4Pxw+K0)4wWRiR$tC45KRn+Te-ZEA{We-PM@D=-N5P3VNBuM;T#C{ z+6Tc8W_lD$NCOcdAm9*7VPOSHVd4LKwGISCndqCyCow31JFKtVOsopY6A@ujA*UuH zirWk$T7hI0s)i>+{~1IMFZuV5X-~`H*0}y+@1VLWxQY?2)&WMlm zX0+2gzSBKGfsT3F3I~#Pn;o^jB15V!Dp1|U0E!PYSl=v-i9*t`30ME+_U?&(piwLT z-PxrID;oG`qDLB5nQWIJZ?`2*&P${)Eko7N=}cbF` z5!33B6l!BvC9*tnxTiOIAqaLE$ z5VhPNu+SUvEw_kmevvvb?Jx#M8UoPRCaZ{FkiDJF4aul_N{lc~y__?nj7V$XR%oMd zKizURp!fVCY9GUTRlv=DO4hM9-6GF*!t3a8u$m&aZ2|wuhg(n49hX-gGYfoS`BTO^ z=ML*qNPze<{!o5}M9HK(MI)yud(NIhcQmkS>z4qL4=r_z3hgi$(8xKtO~*k|KgC z9vfHN?j9lsT zO6n-$h)@K{5F{ZK6v7hZg~<|`GSicn(U61?B&oBW{L{O{t)Bos=hLp29Pe7A&p%Ic zf7?P4{Vj5ST#WNvnLj}~?6Anr98i^c_{M?>{#zAMT#|zH@7LdgRQJF3P(+fe`@AgN zX=U0J4R$k7Bj6rVOQHXDmgJI4=}s1UKUQG@rv;xp=<{kaq7d2fKS@cosAL<`tA_we zdpybRGU$J#|J(6sWz+E1A>bYz7X1H_huWol8{BWr1j!DAy15wEqVLUEm*imqg2A>s$lTip<$8~EX5Dh&gibV8Ngw!kx z20SJ$=>N3kl$2bpQzB_2B@c)<$M+;1kTwQ+ZF+^1>eyJlzxtqQKX10F<}=e6*L6Wv zXYfdKEk8?a%rZrE+$_2})b~H{f68uHt#1~Dd6YapA4SE8FS|&SOxa?LJJ6<3b`?d5 z7i*KW`FDsjflC%1O3eDPPec{(CaI9U-GreOgDU0h=YKld5Q>N8)NEl_hj4qEFS9a$ zdKl~r2G4m9*v-S)ijsd%i8s+<-)LVtVAFycSk9|k}1v^k8U(`)pEzf42mXQz&oLoZyB{iBg1JB1EO zQrPWrlYv=2M+jgPOD8gYA{f#vX0LRJ@Qarv6(f%2j=R>p107?vzRd#^hyxzxzQk31zicdEAODu zgJy4Y?j7n=t>t?5IzCfSMVDGZ7z6$vJnxg9VFHAy-4EgyAN<)v20g(N8flWlQXUPa z5BR(`1w_|L&qwuqq_6Oob`JQp2L!~f{ZW8^7s&M=4$tFcnJiqbtspUGK+h&7!I~#y z83;Q66Y%B4ZiGNJ7B{uBwmH51PCPj37`-#AZvmOY_{Y#1S`I%%g3J>$Y({ zn!Nx&_wH>qR%=US|AqOr^oDW-TGZuQ-A)|q2%HzL%fGHYDhu7uw-Wtx9dOrRjmgcP zm;|rcvF;$XZs$2kEDTMyC_l&eu3 zM7665BcS{xM@uCfxz(GZ{;fRWiP$q-PwsXY~HIm?z%xJ4a8NY)x2na`2m4?ln`B07~}zgn5ZuHP-rs_@0P5 zSxMhDo9E9zNP3RkM$#mRU%AV%+gW0%*lp>Wqex9lq18zxCFxnH=|_}NC9 zcgg2Xp`+;IstMAIpE}i={Nc_1kSC?rPaE^Qk+ir(dtg~LLnE_2z3%oji?dm$?!N`6 z)Cu#DQQwl5ga8CzNrHk%u5?=!B>rI}J7x=(2S@OA@ch(--Twc8#>tzW^!gm4=e>h3XdWV);N1_dwO{)WjE$McFSt;g*hJw z!(stk+vLqmN7Hmb%BP8!@f6;eEUiFf*ELl--wv%Ah>eBu-?NC$irzi<7S0wug!`rH z=fkk(-o)?ST8Ac69fp~d0UZwt8#eteSqRF~vMY;yL6~S}$w5P73U-lq zq-wRA|N41z`-A4%ykGds)+7wIyk8-(a&rlH>BFxtJpN7@i2eiw^1pXt7tmQcvt&LL zcKW2b-YozQrkH@6+MmtH%kakc39E0^i(_CfY*#WpA)U?S?D!c3ym?fK-y|f9V=CX% zM__VCi96f3Ldud2v}X3s;M2o_q&h5cv#B&|)=@;Qv|)wgR@lAPgK6*hz3rF9waYeH zluF#4h3($&2aX0|>5zG5INjds!?drkFTQVFlX`D#-xlzOL&vb~fGDEyHv{$!8Fndt z|B%gece#t-h7YkN(+|uyZ^@yvJ+FwfJ}Quo${GHnvNF&-x`+*$8eMigj5+SfuDOvI z7K=4H&i#QQlOr9|o9(QfsVj?5*UsFG#e$pa7&~r|^W(u9XNa%jjJ-{1WKP{E|5%KZ zr;@jgbS4{L{=Kc8g>NJo<5vtW011YI^c?#H;5lR(g}v#)Y0Tgj{s0GE5muP2?0K2} zRK2Rkd{tD~R>|B+w>P>bS?|-t6&zE5hdDA0SZTiPV?V%5QyAT_ZEs4Rg5Rn42u*7+ zmZldCGt{{N-`T-$%Xf#5#?O%ewDe*3EvSgLP_yY9Yx z9GfGu1G6eFTLtxJ;YzzC4$F4XzzVcS99?ZpIXZ_N}Z?8;d7^Y80cpohJ z)c)O_9Y3H~L0QCZ?*r*W(Q(9LA%Ytouo#@$IX_=f>QEQD9mGEqt1>lRYs}>aTnYKG z*h3SS^?#e}B9X)Mv3@^dafBWf$$Qva6CRF$J=cSCpd^DVgS@vF7xby(BrOk4s?T=*7CDRo9Wv^a0KGFX@rBk;{j1M~Gfa#~xk zb-m%DD1-n*EAJ92=r-4GeX)kcVM?9*6wg_@n>DXrvgn^}1lnKWALpT}SB=2b{KUjQ zj?Qax-;oX)fAN9Sdd2E|n^?(0vJcXyGhEeq6@!&Klq}et)u|%IO9#*Un>IL_CI0&+ z{NKQaGdE=_hx5Z=U|DZgzgNH{ciKLwujQeSxgSoJ<#w6IeUbB95d4@Dgctu# z=6IdUIHSHbtQp?z_SwiQhGUuEoQY(Y7CQYO`wVGL_D|S)zuJp1!){|EAY>^fkHUrB zZZ8QuzDvFK79HaBDD)RCQoo*=ly0O@_tYy~IzL${c&UlyQ4()0Gjm!x0hkM3Q zeO;H|LzTLEPDt%^r(X%#c&ujn?7XDtPANq1`UnY7cvUH@uWcCWPL{7#ZJ4Fo|C^pm z&p(c--l+MjkGSjfOj{V=Sz_#X<`ng)>?2Pfsh(Z#j?B;y?r>VGX1xs72F9s(Q#Qxk zSt-_lbf3iZz8D;`eQwt)o7(#P%i~6XO_jV}talq!|9^q;)HW?%yhZBz<1|^3hhRoLFDb1$y!IpBY`19>)BU@}hP;Y$m)(Sp|Ge>)%g4T< zN&N92dqg0)?h1l<{-U*vT4c$;hDH*CV?C#~Vp_D}Yr@%2%QE}_=~hjyjE7Y=>?+v6 zYl^!g)u!t|9=$mJ1;{^g(oyg8Y8NGU7XOV~|9aVEDl)MDDM}>yf161x{I42GD2e`m z$BKj!>HisX20V&Nxy&V2uR?)RZc>mlcSiW@+J(FGi)U*W2n!3#3H^V^7jxRDK#@xq zG9Ae0ZN9q;1}dI~hX2WO6r<2B=YG4$6~L1QA^*<;Namso%Y5_Px^#MwNp$6l>i{N~ zdKCs+rT2+@;i@M%Dx9?!Uoaw-c>*C^)vtdxRO!)(bmzUSV$|`Ar zVo0;kfRWMr4IwIfbKIU?T3`q|@t}rer{J_oT3O!u#qaN^%mo%)8~mW+mV9pojFvyY z#kBwynKI-lQe=5~dF5n#0-zS>liFKkkbL(r+a zHsrnQQ)rX!x5uWHC`f-NM9ucbr&ts;YGo>O@l+h zv(CNM<4qt8@Xwb{2!M|_GnT)JUr%BR>B7N6Ba1%Fw7k^pYbe-S~EJ9qw+t}HYp)HfDsW9Z@M1j%%(E>f2me^T-A?yTsN=IT|RC3yk0?LS5zK_J{t8fBlt9Wb>nw#`vvU~EzfM`*NENi<1>35S53dI zhjjHs?yBV!d8h)64i36)_;i`QRHNXCN*GL5&oiadVii`L;mkPp|mjFbf~_E-QecpaQt z?)^@#yF0*EtrGNG=iZ^Ig33h}CIS5Fv{+&ip?XoH!i&3y>bJt!pN_!pBR8`)L>jYr zhfl|h29(64zNmGQjAq*GR5V%fw%NqN0sF?cG1A%@`$0ApfKX5qR;Sg41vs|Kn$&5H z+wS}M#HOqcO=1R9#UrK$U(B9)l3_| zC`9!fugZa3Rl8N@Ib-uWk(b#o90P4#t?}t4%J!Dls_YBaE`vM1JJW03sS(@xQyIWv z#be*a@&wi#b4-dydy$xes~e*ApS!YdCRg8IPIImd1PLLN(_d&gJj9ZcJE1Brcg zVUB(c^{IGx)>?qVLdO#`%jz?lJ58N$+VBc8s;7HGRr9)1hOkgAgLPdLY1ytT+Yh_# zft)Ofl_?nV5VxPN%+aNeByYs3!iILhFQz!_yTIJDK={3!fm}NZ$xkdS7a;9BmL{^s zIPcv>o?Ml=FArIij2n`eY(ehHs(+0$vk(CF=o*`nQO)^Tr0HTvDcOw=;N5EHJMwOC z4A`}|B%LiIB_+<{m_ameD+?az0`cqJmM8_y@#6Pmp-T+?LP(?C9a8$X__(-OTd^2U zV9nsCetC#raEp@Vw#(v**#)DF`&EtW5x!atfEl;1$5rQoUi#%}t(9~cUrb43FDGrZ zWUd|8P*oTlH1WCBJRo@6e8-EcI^IksM_hd1X>G(v!Ybv0XX}%dIGg+a`F3@Hgu>>g zreC=KWlCm)2rzEv%gt9l99(RKWSNzRFZ25P;|u(41=bbh@lfP(;t_}dxe4p$=xjzZ zY|(CK1T#BwIln)&wKB%PdUXJJLii9W_Hb7sHFib#-Fj!~Mbt}wgC<{^_k)2Vbp6Su z+0~DZTDr|r6AzzU9m1vUx+D&7kUAei?GFS??XRdT4^Zngn`4G)7=iJRX!6?}vhYG2 zTOD?$$kT(zGh93s_3J}-YwFkevXj7d)V88Z6k8iYQylh(816_8v3HbWhoJ4LhWyT9 zvAOjZWitz|-X_L6U>3Drc@-i`}-AfB;ZWPmj501#R`_@6=4~D;Zg4g*5#c zmbYVG^}~K&%P$!fK}lPh6I53txjmi|p`u_+9X(O6Q?p+$D-9IP0e3L!lZP4oz#b{8 z?$h@4wdT4GNX}2&><5RFoT4n}bOD1RX2p5qc(NvIz}~1>vUxGkw)^`0DT?_{_-`C> z#)l?+`n6O>rsmxW^IHOX3NSeKIU*wx;Q2PRd?lTR4|zskR^uEK}J^QEW+0^<-?IIKLc8Xnd-Nq{a}a=R`wr_9yk_Wd2n(XTDI%K#SwyZf%zN|eYu z9mVuCiaXqPvM_utxfxa(S~bLMOQ0zbe*8pmzBA}TJG*^nxNUAWr0JT^&V#eE8CB6- z{+7_YoQRD&r@m0O6~KolGD16>1E8{gynM_71}Rf`$$dE|+cEzBEd9GHh7z%-dj1rz zqPMq%Gz|3XB4h7ZQ=6qmUQIlC)ckpT{3!WBws3z8SjKVaba=_~HobbIH|9rLkI~Cw zaAy3)!yHr-aPkB+jcIu31pGH01BjM#8wfZOo6PuWE_gGrx7$He30Q=AUVGZW0YuPU z$U7s!((K6hy*fL~qqj;~RoVf=g(hvispaVQ2OB8*H~7bcwNF?fKEE@MTw}pTUs;qQ z|86OcM#;5va|%*Yf9gim)YXessOK$M%^fo~UiUWXwwh*h!4u_r))c4Xb2(TpajZRf zcPDO_6hPd}S*(RgMo^npQJ)d0W(CZ=Ic`+JOsT5l^{&`F2&^ z?1T?TyZUQA`-6ir=T>CA>U_3k%SRS9X3M>`D{khPeJ2#YklbF;!%yzL*daol8+$<% z5;IVyeqV4ibF+q6*^~fkjck+gbQM_ZatWLm*Ev(~zCG6a(j8fo73)mZs(H8tFfa#j zg-@B-mhjnc<{bq^)K)rBtgP|$)jgd=yR=(Fj&CoE9uK}Gzm7@(d(XCNC$h0F%_5#+ z_xY6**tF5YlJX?^0O8(n{% z)Nd^dB`+pEvH;j_LSu1!mIf`$rx)|6mc$qLEDLb#muqv)P6if)w;LXfPOj(&mhAaZ z(ffld=%pRjB)|wHlM?u2D_%J0#RYeKYwoO+HWvQ17rG1@`WUM>oxUn{2C8L&i#%3- zWnrhj2fHqfpFW;F?elJXlK8(-pjJTVW563uqy*= zri_Qz^EYO*T>0R+3qo7-$>RbOuOX6u743e@*0XRYik6l})AodYd8tG33f^EOui*9$ z(eeJiqtDh!P83P-}V$w}`$VxE^qzx$lIKs84U%g4(|7q0izR~`0>HLk+ry-kpuo4Klg zxiHTtO(O0De(ZF5uV0(%3Sgj&yZ&;yQKh(@1$Ffi=h^-4%I0{jzS4cHgVLX4kzA zi=PloM*9G&x!B{Qpp$aB2yQL<5qJ1r+p)86YT7@75=SOa@HbmJWooK%Iu#vqgupd{N=)IOUZQU6J6&a}zJ=vKU7R=zD8S%*qYO#Hf9VSvIW zCm7-KPhfWrJz3yi}QRNB^Mjd9?;8xIlBls5rWO!1XJKncwK_= zgQ>0nD#dDnc)-KQiJ5>)7H)la*R9W}(G3r9Q{>gK2-2>iJ(#DVPdRBS8=m#vEQO-9 zSRuvbaXq*dCV#5FyS2kL7FQfPs*bkslRIYAZ1{oUZ+7XcE1SoC+?wL=F)?Sa#Cp5K zH3p9-4IYObm%UO-POhxIJ#%GcrIAyHS_u+-QKhGoW*-|Ftv`qm4P3PJqa4{m!$Rc` z6VJ&IVEgZ3JbX~l+neX+W|ZYmCVw1%UcQTcQEjvqM1%7+z!RyUYhtMcdEk462hyS)Pqw1=qdOiOEW@}Gs~ z*807dLG=|8-;{%I&D}Yt(!!oxT9VFRayPqx!3G*-tlGenEn1@&{C9Dyh7H|yP6Jk+ zd28=DnYr)wYfT85X1AEVj(tPR^1j-B^|}F-UE7XrDdlh!g4SgBtbef7aHp^`j*tC_ zX%FNP%E+)Lb@J>66>*rV=#@tIp4q#^O+=V?)$W^e9dPECzG$`F23iv!Tr6g9TdsIL zX{ThwSNR=h1<~%WbCZ0tn8hvHRsHZsdfGJuiU!ZUtDI!X!1`A-KFq*$^X*=U>4%XBn?c3 zR;{STj`OMgMH=+l$zad#!I|49C!-PgY!8Guf`Wn>NSKrgs;YsL7W@ToaS4dJzvtv6 zS#fhbI`XE&dW6;rhVa0Qg3{(Y;{zTn(yvfV%f%Vwt!>Pn{&ciyA9+6ESru)M(sK17 zz?_Y)!+!1ATu}3>uFb&Yt>3dWh8)s0)uaBUJfC5EO^eg*o>^|) z5jSwTzG?$JX1;xOO5t9Jj{jMv;3qKEiexS3C8BU?oJvgHW~j0K=i~gmf=$_G=eWy- zWC>kNIQqn9_~liPkf8gYt!Apuk@BRNa`O&R&jxx2vNWz2s~jzxshlnW}MR zDh&rOR54O5#DWa3g#4~^DebDb)9de6y~_9$4Ir0WA1EXD*JhQP$VrI1J?4OxUkURU@C7UnGMm$$EUic zrl`2MYjrg}Hnq+(;>$_r+%FgbtqKb->nhV=Z(eGz9>$Kvyn)Mr?x(jxzH>nW# zQ$EJUhWhB*2>QNN8)9Prfh&ddcnwSNeVUYf-$SZv{%3!mgExU(-K)!Y!Q{WA+281` zxER7=l&^jpGDDlJNNSO{5#mgm=OCaI=fk%h|cvgNOP&19S+6g8C4YQQxE?IBqx7qP}ngq`bT zvHK1~8tM9Gn~U5y>Cua&A=l$_kmYJE?UM;Okcn;3wr(3oFeDoDw}3X8=YwFwXJKbe zn%m!E%;aLxV@zSV{aAMETm)`&2%k5rKrCHE?1~`nV&8S2nou9^jsxNjOkC0T0Rcp5 zptHjoZRz`?sA6NSv(#93%D{Uze@vwx_;3?`lO~j{u3YM7Dlunoif=A0 zPZVARedsajQZ?)9lDGn5UH4=0>dQ*ZN0VH=(+YN9#%W#afEt;@b!z@q)$xTiIW&;T zKWww-GZ<*KPSp1RTkdd1VtL8b_^z#1{`TQ;bxPFThV}S!eQDNL?e~#mi++nHJAr5% zJ1z@uCeA!(a=g(3IWWg2d#8JkYXaBw94jqTk%@h1TLlD46K`=!lCQGA*{+)TqfZ+) zU`~lg++fWraL`8m0)3ow+8cbl1VY3!Mf6g+{2J_yIOi^QnmM&R)^pfrA$=LbdYJ-# z!TY}GbVsZxuJT$<(8uD{R~D}ar-E-;`}Vl68mIeo@lrvk_}{d&KKc3i70y}`q9cxu zj?T=@u^RQfi;az?rl#I#y|3hQW2T;#|H(VP#JY>bMkB2E2ax>=e`9P+h|0NT3{gCkx) z3Eowo1x5h}?i|GsrQ6mzaFLYnxgjgGbp3I5epUl_r6uA`V$A$u)k!_Ju;xH(yF+6*GV$=G(%$g(hQYPQN=KuBdjZ)2jUOFM+a^_}j^^B)+(+s%kuu1Q!?g za?Rt+e%Yph#c5yRwE2i}%?(Tx79RfP!Ca!tbTM6e>A}oMDfXUQ=X0kJ62yg zOF7m+vTL>hidBwiC5&oM$A)mrXwm?x?7)ZVrKJ|J9e=f4<}olXO#H>^)L1_Q1MT~X zTz;jbNGU60HmtcHX)d;&>qs~L?9oqq`B~B;T$Z98_pOP(uic9Jp6I&FQ(0-;2bnf6 z@Q9FN6(#Wf)=GgOHlICjx{8X*`J6TY0v398Ghj-IM{fUh7w*Wu`Bq)M8{Ck1`E=ue zRQ(^kv#O-9aO1S)ETK?3P=AYwV)HMV-@_E7^o*qgG zDb@+8=v?|KkV5A#qW`}AJXg9*Et9364BPu(o2Tk8ZU+?a{sF2@;#mq%-bZfv1>;zo z_6cfFvhkxe5-}CrBB;NQ5Kv^IwtDL+%_?G9HwllFZHJ4V{QESfIyLN78C*E`@ zjpM8dGw`E2cB_o4y-C-fOfCcqK!hZCO5e(^>JRk*D!lW+LWcj#13hz(UE#849_0o~ z6NWP}#f4S|7XXZ^KpBRY;9SW+>blp zcXBC6S0iwBb7M7J2`cNueWI#}1y@TgtXlHe^fR-K1jj$7${h$&!MWQj<}x*W3I4EK z7Wa3gKr6UhfD{46JMctPOzsh?Y@@BVy6aN3@$L&{+N}&<-XlGrsxr4QNZV&+(1%eb zq37S-YnO0VYk}J&jC>ku`7MKGfs3USPIuy`Cc; zoR0k>O-)a~(}_qTQoy(Hg`SQs97E{ompF+RmXFVC`GKmcD*xpOn*)MKCK;%cZCSIe0`xLZ~2SW#|DX+-90EjMYfHuK>0)~gS(ur3O z?(U2t;-jXa$*QfzYSmk>vsP2XfwBZUdwU6{F=I{X=;lZXX)F5r)uCxaO3eauh7 za+?<5lig%bK?_v6Sd2N75!IHYt6A@QUb(I;j(CUBf?m(*$@>PSaZL4yUC5tl%%Z7M z)F89k=_L-)L2PBJb5SYtNdO(V4?hujO8^PDvNQ+>xtH=s|kou*B6y z8eY0&X~7n_ahh-JBtgm*8D*&Fd)Py4q|4Lbr9MPehF;!ehb+&YE(^i__Ow+9x*xq# z!Eq-pB-wip`To7ZeM0d(!eG=nAZbZ)xI%DjyY7a(?2pM|E=y@>IryTt1!E4zgMO{TPrH#M;=i(GtRMoQ7a=1?It^L_PPS@dE&Ku;43ve3l@>8H}cL9QZ-lKl8o1TLN2pq_=Z!iKZ*SmT{*`T^n5>^G~LSZIZr zHq2>$z6u<&2HxBmQHi1LCHL6&u8~I+P;&gL%Zhm#>lwCmG_Zf`rBYby{lSxW4Y&I< zE{}ku5)2=bb*XlHy!2(+J_vP%;4CV;D(1@bM;W#vbm)|tj!SU^8P@xbFUh6u>cokqw);<~H2AoK zy4Z^uFi*S;Y3;5>%$x-Gw&w7c?G^@)rI)Uh7d_ZvBOoQ5WiQwJ3k|coua%p}p%w4H z5k`MS`W#VLtDFr1r)Y3g>}C$Zi4N}?XE#=Yl1TW*${L|z#m2?$_lHMODA6t9BSdd| zIHZ%3l4`shVqa1a?)gbEKU^m>pq=hMAtIu zQzbvLcoK>7q{z&2x5D|_a{4lo%||!?6wSX07Aql&>y4@suip4GnB8H~aLYf-Ng&%k zFdUN7_#T!;;Lw=X|GTGzy%oi}=MIC@zChBaT_1}nXR!p#v6sYe>}TM>w{%Mzu5;s| z6q4{0o$09!tSl`NV4&!^{l(%%^Vcsder+;n1Pf|TeqUFx7F5Xwi){LL+#2uA9qz3+ zyUVV3_^^Cq@0I%@_Cp^YaI~!MkD^sg9{bL>kMV-6&_~|wEbR!#CYoM?uk%J)7^60+ zsA(*#xhwHKlZp1ezVkh${};=7`FKRG9(M!!(QUvf4G0TYMC!%+LVj>8{ddCL6xN49 zeI?p^duZW;d}2SV_VMG#cc{nrC2=V!VWVc`WMtX>SGBe5bLG0yN=oBnT2MZxv8gHj zfidVbG>vN@ve%8TFr78>G&7rqEBHCg!VJwGv7fQc^`)D56=gJ!K%>nPrKKdbvcwBX z_EYzj=62}J63yMQTfzePV&ds@Ik@!r-V@SgR3ALPmz65EiL|jWJn!@R>#zvJ;nBC5 zUdweiICBtk=9!N|@P(snX8BXnvnIoLzD!M}g(Xex>91C%l$aL+=c>)LKU5<}O?c## zJXNLK(etvqz^H|o;`dG4izY^*W;iIn!H{-#7boAQw%^O`jC*Ws6!%Rz)~smzT}nwA zV{R?5cLzaV5nG5)M!%eT5MbzM_UUFkR{(5Fw~EkAJymS7bH7W*Mq^xxQ(d^~n1`3t z1%62dLY~$*k&mT5`un@O9vbZ3)9UChB&0STWWSjM&~JwOiY%GI=hQSnocnAumZwL6 zY$6YLEIwBo0n2a^k5aDetzo-pW|lL&`Mn|+Be`}#Eloosu@zkB+R<2T=Ovr+e20=; zUrmJHjq9d$5T3=kZXIe3ICcEaof!K$teUSB2b-LrJT#ZWDIpkzwXoC`dqt*4V`5 zfCN{+&6(lNlu2Y>Z-fm@ZQ)he^a3;yy zP;XWp8CL#tWV%dFkmxf5NYl@Xtke8si36nnUnf%F?R29}1fn@AVi_=&0r8y3F%~xZsi9OIq#OfR^daGnu{M_#D zpar(37>9*b@VuzY5Pm&tj#wC1zhx!`sNmq=oM5Qhq+ob ztq^CVoaETT9U~%=lceTceVi6F>dXi(U3ilD+$h{Gr(8MK#tMY2w_nk*=9-OcH8lIg zGA(fQ`J$eZ6)Dtl?eB}FiqU%%4|20WA?h-pL9GVJWn2`F@pb-zsa7l*Bfp#)%cHbZ zD@Jt7M8I&+hwq9&<@vSza$}RmCAU7$f<&`;hN%ff$q(QTMwjcBFc<;G+F-re@p zqJHFEFP9Hh1v|I>kO4n5x1X5l5e{llz5J0Ex7RvbTI=R`LaG~0l90R|e6I96!1Sn| z)&4+Ek1P1Rl6Jw&WB)GODEMa_i{?#X}CPw;x!3UL-?7(Agkr0 zwqGHh0s?893}062+2c^Wsm;v|2uXDD`Uc|c(1gl4L$R7wH> z>dGnuMTk{!BOsz)VeU71uaFWSa&iYQu6NCABD@G@J;LsD8l@a+Wc=!xwqKQ!&yC~2 z?zQHhEYn4QgFR{ZBEzs8-m=(n#Vo+vFRb+B7b-_ImOnEl6dMfT;cK+i6_B2;S@>hG zVCDElhpr&FxtRzZzc2su^9r>cw?!?_#0{~Va?v-g2^;}&x1w5Wn_rTeHfcr z-1G1(?kZ$H^us&qe21>w^uN+T$lfzS=O^%45vp$m4f#2$Lb2(F+}c@cYx26kwoFB@ zM_jw~4wC<}BCmUD9gzrSv-8z$f=WlUMhYUmBFvVS!jJ~WhQYU^pZVFB#%Fu2NFS}r zw$@FVJsdu^M*-7o_diJT>r{mjTolttq83nAghj3y=E|c2z3MwC^jLQGv4>k*+Vcm;B?k)7y z!FIM=nmB8BYH!&G@Aj zw5^-BHA|`5^8ivot|mZ2Hq>&8>l7M$li$0L%=EGqp0R7?^5Y3+#}&V?npZk;1{<4G zIQ0!(>;Mjg__x2MJe>}|`w)Dx)L5B#_B^=1ygxDVRvIEMYC-xe$GMI-RS{}vEfih# z387$W>M=<1I}I)a&0hc7wQxKMijmWA9M!6P*!@CddpAUqet0&PmKjxm$~`mJQsiMP z{FALZN|~_Q9-|SN_~o4+XqYLa=|yg?Y_V7Rk;pgH#%d)A_)OYIBrDMBEabCDEY=so z?OnqbUf{9rs`9Dv%OIxo55@*_E(O>L4UyJNp=IUoO%BRLB>f1ivZgzMvZkJErEg?* zTJWiph!<38T1_;lyUS)*Dx3Ys%id5v=U6n!5k=+)(BX$Ee$db1*dats7oMU*>tt-4d37=NqPxcx-qBmjk#iW(&93mT1v;RJHH{JFe7oC{R!oq@8n;c|1BBSctcU}n0UNPFWgw_1A)c`jgv zXKMP#-!cRVJvA&tf)(arIUr3H4XbQX+>XXmQIV5TI})mjnFd3CyH}Onua>th6VD~Q9UQ&WIK z2VH?E9w1V;$D5O<^KJ}!oyK3jz5%lQ@$vDVcbmZlbVp=HBCKuNz^WW41Vt9r<{OAPZWC==(e?XN1Wwc{WXTMS(kV)9s(GQMPw}kQB@fQ;E_}- zX*cVFqN8tyKNiMccj2HF*?5kW$m&}%4bINjiAj=cV!S^kd~1+Nhx^`~d&Yv_K4-L> z4>lfl`=CZQlego!?pZa9MWT^kr+vgur)}DL%?jow`{FXoHV4-V%qo7G#4o>oM;dNBY@{K)Q=39 z$c|_jHckrLGs<2n(fPDU*O!LY`-+6A`Cxb0M@7|afn(ABs9uDxtq&h8uWj!fS%Zj9 zWEwdMXb{5Kq?>GA314Mdl{KuoOQ&N#k#u%dwjno#8OU?dbJ+amCf$3-@}ru^&ceMx zt_U*8t+;et>#`Q*KpXGX(8U*3Pfs&>&8@?Q$_phU=yP_Um5vdX1-hC z2d%SZAe(wuY3*9k7A>w}9EN4vUZ6&ux#x@2p?8h6O|r88U6jq zY~VDWO9AtsOP=-J_xm<*1>q_A*hFKzQfM2?=eHgGa0x)&1vl|T*l>THRD5puZ|dN& z^w20<@2Mtib6JnNnT)X4=vxj;YgO@ z#I;(Y;69WZ&z>eYH67de4fyx&^wGU21zkrAS`Y*D$4#dSZxmIUnos%s9MozIqQkd_ zu2Grl-mfs9-ArBVsiQ{m*ewpO>U}R-mekA(IAr!&NC4<--|Wc+88EySTa0d--*4AgVRCtI;k0?@xW76PbleWtZ-AX<}^efoWD+FhKBjxi@CU7d1m|OhO%Q{)|X3#_posDysitu6K|>=rFHIUWa4bzep8>Gr6?O&$_UMV)B9&R z<7Q3S1k>Srw&S%Slx6Fc-*^&#qCe!+ocg9L@D8OR=uiUQ`nC3Z(7O>-ZRX}LzSz5p zC0@_dq=lrJ%z7lpsP}-(gpP2=4rYoCN$Cq|81`02(Th`mVtiNSS;hcW?o5Z#ExE^} zruKgi9MzAAIvVK#Ze9(qbl{Hh7Nc!gT_D_Kb|WUI=(IYx2Fatd61h$uHF$x_j*yck z^7x`Ni3YFqQ>>M3h-Oa%8aho`jXEXWhkWUAz9n`_ zuBt!miB5Bs$vRSiHNZm+nl>Sg^dggxK?N72sqSc@EMm_Dezie&IbcsJoZ~zUr?qcD z{hVuGV@1v2_b13qRFH*5#Iw~;e~!E8-P!4num#?f!X^09@j699tnLm>)~Qqsawdu0 zJj(C#^Ejns4oyNe2;v+~`YH@(-fcgV?FUB=XH3-3RwQoaxro4{G3lOHx|}{V7lfmZ z?HYY-L?0LJZ}iF^T$R7`ZKCA@XtuJ3rwiLgL7TXa36O6lgxZW&UIPY>WG4%X zUD9;G%4P~w?aiCMj@^Uq*%W!uMdP8k{CTqj;GG^p{bgVtgO8+@=p73obebcW@7)+v zf>u(+m5x}q9wlW4FZsMnK;Z|<(N!g!PkHof^~#;5&#dD<@~r=G zIg1JtF_Ob&!jHnVrdV?i?{Vv1@5+lx^H-osE>oqD&_klSMp(~OLOwapczo|fgQpfN zY+>3j^h~x&Q8TeEB{<@hLJ$q+de+Sat+B9&Uw!$NP11>M)%^Yk&jQcFx(TF=(U1at z4e^)T$xmW0SY6Rz1fum5IDdKyg|2ZA9d=YM3m@3JJXNfz>Z}SC z0Zr|jYRscSG#xz2=(C|xM{VNkGhyLJ3EOe4!N$xvhhFS-?t%k|ruJAP$^4~;E*8En z?7`d=#w!S!_4eCRTlyBYv1F*&Xsr7HBp8sfibm(tav)K-E2I);jwX3Tr zw49Mu=J;b{+c|2Wd|O;?96B|8`N>D8SyhsORz^7EbU{8iKHBdgkXaxq@&&{l_XhK86GVg&0a#~*~CU4$RE!wzWeJ(bEsc9cGmxfLr+|p3_ zG~M88b0On!@))&%m#t;}#e5O{?Xs9#`7e)#FU7m)4v8lnCAuS!Tku=?f>T(zN-r5P zPuVpM)KM3}pXk&#XRv0R`0^d2F}lC!IfO{*(w%4KcrhBQb>x$$Wo=IUR6CrXyj}F| zAlHXM9oW+*6R4!Tj4|>LZekoy?z6x)?y)M}Z0&o@6Z*|=XLL*73!+rFwvND)LI-Pn z0OP=R0zBU!ZIPk5CcLzo&7O~{nS0=!uRb@Is0XAyuf(;f(jS}81u_JBOR4r4J9o&8 zn81*>%-0doTjJ^#4&_Z}cW|r?7W$=|Jd?pxjpFkXjD-s$x+pHOs(RgHQy&E%1cQld z)Yx)TrejmJ=4=@a^)@riUey+0+U;xsfSsD-Sx{45N_sqSk4b;jaajgc8kwAMVE>a` zMX^mpT6=n_u19jaCC6<=VFwk(#)hwf)o6HYfPLw6AWL95IdO0x-z{OSY=%!>Dez5a zSrgg7=;NYQa#c=>Y;P}!6@Unz(Ea)o(fzw2gm~|y*redHA>lVJ{t0X-^o@RW9M(9MGy zA}X@OzSWIZ#elR>6E}WC>?ycOzt-D;ZHCZ;u&J)!Wu8j-v$qyp*C^~BgunuFp<=u& zTF#^eo*4j>{UUbcR@UdDGh#ORU2O4A2-^kRW^7gm90@kN(7(bR9~p1Zf`#aYKR3h1 z#l4k8I^SJc(9k>G8qRlKzN^HUv!SOP#_m{usND@>78;BE(ccp4J;RRfys=dRIw?Jm z-l}UWYs!sh8q8vF+kdj9Zzjv&lj}OMiz>>e6B5cqBzAqn#5A64<>e*d?3@vIIGH03 zMT0(dFSHqOn2q3#>^<86EUm2UTULFJS#TC2dkUL8n|S;)%%6v7#5723@8~@5Ph3D; zRS}=);Y6Kw{Rt3%)t*Hx;YmGGGkHHO%2+RZ-I_zlX@{bRdgZo^v*i?m?5b;;@6!P; zYJ7#|<)-EWkBEVGvsE=qqhpqcmF>q?#a6GmT;iM`G56)~U;@m3!rx6U)tc*jT|#~= z`z1E-U7mwPYtz7^nq|w(_2Sf4d%vF_-n{Wv1abb!cuch3Y1X%-b|Uye@O}Ud-yEWm z3v+Hb;U)=cvtVHIX-^AI7vl{KyvUR`j-DtT?eX;<92r>Zs99&)j-ka>)7NJ_Sqa2& zXRj@@n$37cXFr#i6Dv?!n_2M?d>{weogAouahOtSbumCgH(B z%qQJrVyDyVk(sTt$Ml;uT19%lF4rn3U^^FTCIAllRB(d>3nh2*hJ61Ey>Q zr_=Fi9d|Y8>E3UR_%5gN=@G`YhXc#D@m&kUWYvkz%=aKKhA$fePHyrUp_TS7uTfYp zm7yL&%YMsS;~Yg*5vBT_0>S*=rKnOCgGVS_j-$A{{H)Z;bl%1g#2yzj%R$-~CJ!Fn zgd|BT+|dPgfbDbr;m;Z8_zKOz`0!ztUaHvLny6arC}R|z$9k?}OnseMfAvJ`-RI2t z3x`OQlHPCY`@knxAi)>}z#TQh;C2Q;k;QL)wtrZ$BJn-G|3v1`0`|eEQy4&#}X}?zOL`aBVuWw6y_XG1ReQG?d!2 zd@+qQH4)>ob(oE9$@)b#C&JQ-nX%_tj{I`}jF3GZx_1!Xm9;dMwt^-@8q@FN_di4Iaihk6xP?6oY0mJ(O=Ja#skcDJn1SjiAH@YEX3X1 zXaJ_zTY_9sb7<}3QCn!J4>)=!AG$pPWZ^bUrcVX(HY~5+t?W8*2nwCsPlIh6Qb$Hc*iIL?WF8>%<`)-~YvTm^IWe^AM54Rsv@j(V zffgj>ZH3BOKkWXVSiojC`*uvT;WhQx3u_bwEzX<2>yad#BRSbgUvD~BYc)0XvEVXuAt>(X z@C4Q4)i?DFzIGRUWE|y)=X7s#SacsB1_)o2?sbYCYFjz&>Nm4IZm)Nl9q(bh*c(m7 zY<%Jte_8xp^ZO?~U%c)DM&Vq9JJ!xr_Ua zui)TL8KT%3SNkGQT}GR>$Lqa72UMOtu8bV_k^#B-%UoWyM3R-3w&voXS;WYt4I^bY zv{bo$grr6@VHdSyperxQC)rw*>+Y@DSov~vGiTZF9T!y&YILv(6YOd(McE^08=|hm zIPJrd>MNSM_hh;GlFDM_lQFXB9#(W>>1Vwh&axlX!r#D`uczbU)JSbcE40~u8C+L) zkaOqv0f55|0W9N8blofUbkA}f`XT$aNHXisY~MM#CAp{H;sW)a*;849B-X}4cIayY zR#cDfqgSK(_-O4y2S{Sz(n=R~zb33YDuO^Od8|C5)J}s{msK%XZgzk?-vpRkBB$K@ z_qdyvkAR%nOh?{35*GeG(cq5-tu#JLFjeXI9c>9z7iyCNHRuh4-`asyo|9BNcL?x{ z{T8MZzQkCIx^N3J<{Af!jUK{OQnxdvssIW>=A;&c9@gT#D25OBu#L2MkJqey z#S~c0A|g8~M%m&G<(`u#CT+pEF!gM;ZWabs#I3a)(TBnxKg5tLK>vdC#ipn*&n3jx z2})#>ks<3keC&C+e>xc6=)UGVAi*vT_$mTju$p&zJgDndGjD1DMTNWTP+4tzm%z&0 zmv4vxA%Sk$M?oEWQ+CcNrl8`kYf*2g}vRz((mP-i9bB@*p@Rd>IzNAkc zYVRdYE4g*?q)_>5TK1z@))6YQ-eXtdUrSF-I-iI}W}JIzLzJD?shvXqncvGeS%d-P z!~hz8S2hi0z2$+gz2;yerA;cBTB7@Jo6|09L6EZ^2zd)N%a8r9*MI%~|E@){r2n(y zzw4a{yQOHoeP9d0Ym*M+;n9(Olg?;<_}_Deq|qY;WI-|~EqaEBQF101xJMsl?tcky zBPuU^`~Y2IgjhXK9udujW#`*|)t!CkK+{In`x`{E3y;#0pM|F)nv;s3jK@Wq@f7+zjZ%@FW_DpkLU zh``~52Ob_;ast+5fI!a0#l=P)#`wm6UQ;_gs~H*^q7raMOiWCeO_!=*#@n$75AgEBpJ$h(EmJ0L1Aq4RV&jXVqaZe zZdrVlt+QQC5%hW}+<_|Cpi9<~1S$gT!NEbWr;Wbs+@@tMdPCa3gG0Wl2mJc={^{un z{eCINviVI{cXyQrJ+0Tj7%J}brgg)Y=OF36fqta_|JoTA7S`Q%V>OBbb9i{D^6>BS z9Qye79-U4WYY-EM11DYWYzcTAD6X%sgVA)+g9ECoS>xOO>n~B%@UGGBP&@@CCGpkL zGN64lUp6%)JbXJr+m>hlTD3%N6WF5qf2@{&-Ug3n`V1UkV`HnRt1D}2x=mO?pXW`E z;Nt&W;EsIfqbrVH3y=W?myv(JP21bs`|j=zI)gxpEJjAlyLtIVklr3##hm!F;L$2N z&djn~i$mf~(m#Km+`i#X;V@{4 zn3+)$@d0yXQ#m!t)QXFX7phHB2so`bq>b*e#XV&HS$;{&Lg6R>RIb~SP-ity zy!v)8>io&;d|PN!8TPcrw*S2rnug&c#<^Mj&9DDOlYmW!>%CM17k^~mL=)i)gmQu? zLl(}FlUwe5dCvUu!AAa4HxJh!XMCR~;&?I_uNW6{vEIkhzVr^xVa+%WKf}or&~$TR z$p55@pWl|__S#0QaP>LoEc2`1CjDvJ6W;SP%rX7znInk9T%ecZy~8HCOmp24i)R}) z$omnmt)^jn$fsQxtjTq8#ZMJ8|CEX}FQ&}zfz`df_|CUw8!f^I$gC)fv;F{)IDPyx zaOu9ap7eD0#y{$&wWOhPV>mv`dGWd}9`e*f1 z##c^ax4zX(#3lW#S0|BA6TR08ivYGd>fDLa+{o?uX$J00ZQ;<_KmCto;$P+3>0oRKQ(S3(Ctqq?<91S^?U z8rCdUEz3`7Hyrj(Otz-T(^V;J0^YQ%l#{p-6!m}N1Xj|zD~ zKkI8H(9F;t+XW-KQl5@d7IdIkbB+M{>e_d`Q1;HRhd!Mjb~ujr-C(1mQ?*1~m&EJHZvW1{_(NrhkVHRx^6S1kuymjq;W(RdzcD>s3@eRkS*7)eTd4 zIw~e7x4O^e&t?u6mjg6E@9=yXc6LsKaAjUdF`! zcJOHXpy8|;Ge*QwAUSiypCHi&=mez0#gP+a=`E-22`aBaZlj$PI?h7m^=RM&H{hJt zy^sS_YkZFFs%CpgB7m^pGg!!rIJs|N=lkf6!KUMPyml-jz&#h2N^AGdxVqvFGNs|h z$;xfwTxr?^*)$lCH9{!XU?s+Sk!>*of5v)2l1beAQmM=hZkKs8HP#cwsy{1>zS`%5#zH3HZ`@Jhs%SXGSZpPG&^sViNTvcjy`F9 zOQ<}brAkU@3T0JB9Tea-9Dc@7W}}O4B&wHt#+xDUa=fsPB0Jd{##?ygAB!#uc;GN$ zT=Y@i-^!DwvBPI}<_V7Yeq)0S20iK*15ExS( z9w>uAznI!};|66*>|3u2JQ1c@zPxQ&IDz%R=B#y6a#d;U2~B&wHG=XV5-1Iq+* zOHBcINs~y9lSXEOuc*rN9Q2pH;rwil@S;Gr81pZaZSLrpYkJ?3JKqTAcLx{dwqIO@ zZ@b-PTbxU6Efwe+J_Q7XC}PU|&9RhIZb{nUGot{W7D@asE?!paKUKC`6RXImf{D~c z4K%AFA{j}xV)-_?3J%iv?$$llp+o#V>-mQalDz|1wb|$O6+T-Q?RK}!rU2q?vU#Jn zmnNKd+2gI_%&fBngeA$W7oXeq&WQkTTXZ`WZq0B^Y`P6Y!Jt$C+3Y*h8<92r_LRD0 z&Ev)$r7jx7`>AgoGT$<5yV30oQEY13_eOE#Qoq*;v5Cbdz3({YX`+A4i^`CM-`SZH zE)h{88@g*7EKMIH5gtioqaM&6sV-hKx%;-cWs22;dY6&Dc~G#s9KCEiwgY+HQK~n_ z&wMq<&xEZFA!BJ`f-V0fGX4%z;oFa*0uprviTx~CF%3LJJ=>u}Y3fz9JK|mR>oD_) z*U0SP;o!=sc0rHi8a50;M>Vp8ATl0pgZ@G$k=B3goUB(yv!{LBo_a4z;_!Rt9Bo7?`p<7tmk z&F6|%P@@gvJ)NVlkrnYcP-?T=2j4)HzerP`Yr zpxP;ez~S?UB}!B_g}XuH2=`Oxe6Je;_|MOcFNebt05Hl8gY}9boHYe7+UCxcbE>(& zDEZIdJnGv#gob&B=$3b`MgH6_NG~QgSH$0#!)@4cK=a7IepM1lfYeE4smKYxV>q)T ze_PRYk^kB9P0MO%P5u-nj?BwKO4`@Q#VCl=(p=o7$6bIidGcaQ;R8?Vth1Q>N$e}c z$8-H>28EXH?~0Mn=Awe4j6xsdFwdP^Fp$~2#$`Jq0(Qe4D*@wXnlZRPueU%y_u}*R zCMd?*FMwhK9Dajma>mecCy8wLRTid3XuR_)b5Yo(`5U zp8E)fNyszx_j-^eUzX|QOHWMG<`!{1QeS2~?lp$Aw{x(Op>^=Tm| znnFKQuH*h>nJ709;yhO)ac2E9+jK+^1WO;9OF`J&TLgIclKa?Xx5r@CS)IAK&-#Aq z@~KaeM0%ddxKo{k%|p|zMq!Ea8NrrsefoZ+tp$~j^JDB53+x!E;_md1p!OG&=ZOiI zQX3Z~`Jx*~@hTxu*TH22IEjB(R?qcHFG$ymINg7BVcxT^2cNF0nn0-lpBL7a_5GR_GXz}ZvGcEb~oxKGE~*3V)?sD=~;A|(9L z452@PYr^<$(rTP*f~A%R(K|d52BB10upsm+sIi)A~@NM;lz~d+mP8ixd{##^L|HCXZG`0+{fo*?(PbG*E7KN9}*H%hIPePG7K5{TP$KUJVQDvcz=-Gc`o9A(VZfdX5g-o%04EL5|%mvX+ z(`^Cr8F>Dl^)1ZU=2K6!Moo4^V188&{etu#Nj!G{ghIHU ztOZ!h7j?N*;v3rfqJ}_X^braQDuYYptTUdIr01_6TH4&Bf^VIuhF(yt>K~2zvNpaz zGad(oDTC=GNeQ_gggcAJ1U#Yhg9gZI2Jt@^0pX>24nS&QRlNY&G2@qW

    yz!$h2uU8LHW=)v=qIKW?Ivw`mKQkC5)>xTSnz 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 literal 0 HcmV?d00001 diff --git a/doc/screenshot/07_state_overrides/0702_overridden_tile.png b/doc/screenshot/07_state_overrides/0702_overridden_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..db2012e99696cc337e786e12b9dbea4d1962169a GIT binary patch literal 36046 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 literal 0 HcmV?d00001 diff --git a/doc/screenshot/07_state_overrides/0703_overridden_tree.png b/doc/screenshot/07_state_overrides/0703_overridden_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..ccf4fde4ec07c3b042aac2e1c4ce13ed3bff5f32 GIT binary patch literal 40178 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 z%0ALoy>+oRcT#^AD);47#dpD(<~FGysry87$auXX*@!&C&&V|KoB$NN0MAb)y~*`P z)Oc#NE8a7fL+)?t)x0O;pIGDE3Y#!mFUB-wMTFHD*1+o62=MdET^mFgC-z0rBcsm4 z#xCH7^igo=mWI~LL|icrgpwTSd$@&Ha&_{LV-X9+-d87@5vcvY|p$L9H$; zg^#9|yJL#?+!ho~Rcn3BY}94-AxoO}&nM)gZ5prPwTv{bBv8mbUGr876eXv&!^?vD z8A4o2yg8?&&7{F=6YMmyzh!P4uE*G_2`GARcbYwd36)K5Z$*S6ykcCp*-THGH5I_; z^g6#DArY>v3=Mo4e3GkeLYM9x7T=|?MV2D)x6&A0PP-?ZE-Absb-YflgrM6W8T!Ry zBvl+<3o;y-!$>7%nzrg+TL?ZcXN;Cg(7p=eLx8^6O>#GB@9|1Ip}@3y+eb#pGHr$P z#?5-S20W*(S14j)2|qqks!XVI5u}uSv?m>%GyS|MCFEY+_*+5!{f4Vm?R_AG5;ko6 z)n7R#jHcdXR<2Iy=+rR?v3SNdXv2W zpu}einO?mAi$sBG=`ei}#Y#Gg@%h1R{lF6qX$ZB==<(OloU;g45$KKe-4X;Zr)hQJ z1qYhcYv8xx0$fU&tC=^h)F!n}SX-K^xys z7I8I}vUEkpP{+;3*UhB@>sZ9M{N-nL@4LE!Dc920J|PhMEfTA-Yjw~67VoR|uL7&z zLa$!rbf&_k6hF;?ip@ncwI8qJH&Fvf+z0IwC7su&uB7o)PH^O9G37HoqJA$Qojv|0 z)L7#yH#i}ZBWM^GSB=X zj+F1!1N>2hr-)AjxhE26wz1N3HhhH;$MVVYraXJ15re7RVe=HLIeb6eEBNmXu6f{k z#5;bQKe2fgt{jGPN#R&Y%XGEPprcm%-I|^pIAOixZ=KED;)j1iC%Qzr3;kD=p>zkt>lk12XBS=HqTF zG`KdPpEee>dF@)vg>5`Obd@4{g!Q=B9Ed#V^2ysAPhSg}hsx|qYr0p>+dltiCg$Nx ztw>Yi&~3`omZdzH{;A-8KA`yibfl;_0@bd4nWD1JnzrFde(3HtbG}o-&Fe)0`z@3N-Lgp~!N}aoS_&hIuMs=3e zf)@R~ET!exwHeYp{A*OL(&`f9oKx4EWCw!XcGY1(S4W|$Gu2GWh-_r9%zAXSskVngdAi-kR;nxx1{9L&Ni&3&cB zZ=vJJcU=o}8Jc75Ddkj%XyvFJV-Ck9-_sZ6yC2WY7%S_1M#VtNhj*5qUb;HR-yBKT zGbu*Nsa!NT##XZhhddwbJ0D;j-+sA|!aF$(Z_JLRW3<)gK&wvNzT84Rg%1|tb1+zK zy?wQtqbfEFt4 z36OBLGsE2bhaK`4bK2@vgYIu=f@|0@_R{Zn9^1*C6rMsUe=%nocI5593PNgFUo%E< zq_|18vw>+{R#}pD|0Q~Y__w(hEyOG3pi-1dvD_fz3&$%mci#+|2S&afR-)#G%7DP& zRN~Q02RHh(DY*(PScKdj;C1xnsTMS02XwrHM3JLmVB`Sn2w?e{Rn|Q|{B4i7%&0HP z+D)5|700KFlA9O3*gTBB^eYjH31{d_WEl($`5_4+EDj%k$MQO!N1%?9E@yY59&OVW zvyN)2AcM9q@cKQm2ebUEpURD`UPXl|3g|6s(#(}I>IN6A?43LEqd z!!d;!PmQa>1Y)BaMBpm72q%7_$h#NIG8!)+3wS*L`d&=ekB1558YasR@P{7qF}Z0Of`cz_3|=i;_rV>eDp?= zA9ZW=uEPImuBqM%pWrj?cYZkGp8%D9#VwTlYQfejbSURQ|850Uk|Ezn_A#jN%FA*3 zhfuES{TqdAo-;x3UrQXli}=H^q~23`18E_b!*@xU-aDjU>u$dH(o^u%qBiAQ?@XSb zpHvkPq{_+;v=>-^x%VE@U^_nQHmHP*!1d6jDm|;xB()MmHcwB_OpiTAt?F-|b1rRc zY@80}6H0ZP9IlTIO@~vRhuOZmwmh=+E-z&|1{Z7_QML8G8!4mYbnYBICz(aen#{18 zv&~b5yz+{@vbS1F6KN^Hdq8!9(72Oo8x>dYy$(A1%*`-5;Yi94b}{S8xZ1N`ytm|2 zICGhPh>h+!6@0pC-!6#Omam{Kr89CeyH)!d!=0IdEeI9xtNexK%&7Mn7gAu`Jh)}L zo_v3J@Vy?Mu8s35W=6oLgCQ%NAZ%Zt6kW-u8vQIsRYM=HvaY!|_sOf9-`mVl+?O!| zvMoN!I;F%UQ7K&?|-H3T1|C(4>2*h|{H~A^n=Bq!@upYVkpP zZF4sibQ=1nYe1G-a3*};>;A3Ck;r>b5pPkupUFe%UZtDS9?xOHc+o|C=YDBZX>Z4L z%6zps(7a(ZkW?>Fr>rf!f<|clGo(K~F(SZ9t2I4C44dQOfkdJH!9!=z_L8;VQ}e2y zX-$FxbSuoAd^|&X+|q8nwWEeO;z?oP^fzz;F88tCPdD&Xsn5gBo z(K^-894DEAt-|b&Qv-}QbWzt{mNniP{mW1y=$acYE;BicEEQD=v8#C2JTfWcg2w%! z7oQrpEYS4r*PX_tIC0>g)Lt-i73wH1U z{IIv3fc^Iz)%=XqemT)msd+lWp$0+)z4uNn&PeN-8T}D4!?N?`p~>?$+iGGN<&){} z9XwD-NJxy0b7Krz!-Xb# zS(OO_F6GTc(S>!}lvY*Rgk!^2rFNv(j>tDB@&H!6d?x31QyKS!h>cj4q$GwXm9I!R%d_VLC!yCI%EHGLoMe_1ckv~FoeWdmk0ZI7*v>3Y$7wm4mwglSU6B^b#e>Ya{qXIzk7c?S4YMQCpSc0y*>j@8fX?I&!IWh#Ja64P!gCAdviLD*xS~OW!_jVuOfPC){&T^C+jYO+wocnr z-zS&g`#Lp~_fxSsq=K>PiE0)H)5WlQ>EVG6?JI9cFCObIceZ0qN@gwM9nNtV%JfI< zZKd`}7@>{*Qw+&El!|lI*R#p*9(3P6@ns=`3iAc~+8{V`(?E{O&2{54G&f*DOTc}9kyldTXqUfP-lyYfCQy?qBL~@=fggj zv)_k_J9x3%*VOUaYJA;_L8oke5BzW{PvO8{$;*m;=! z+FM<>?uEyd(X=E73FHp7qv-BaN_adMy*=sv$}OMBW-`!KRc;jR`AL9ApV)EaYR-E_ zJSCko+=M&Jz#JH5>7=2RU0KvwxW*epjtewL;C^YZJ#BcIE<~Ydj9~X?dPP5HL(EjGjfG%8FKM8d&c*-t>?>nl|xz@GgQJ$m1I3Q8M(#?eHZvA|-Q zsQl%7X(hCLSZ3Et0Rw+F;SH!fN2SzCBWVZ4(}jax{>s?iB-?GED^2d(AYU!G92Oc} zZiw&{y*OW1cTf!p3u|2CT9nF(DK9Vo54eFoCDcVgOx*YTbIx-Yr)Q_ea=Mst|L@34 zX=!N~4EC0dE&uoLkhQhSLM0y`AE({%K%f$k%WQ-!HkR$zQ2p1{u|u_95l>5AGlhEB z)=2vd+olZ=ZXp`bChPRnqLK9~ZxyCvjr@$m#RwHSx2t~o!gPq zRl6@dBC&`Y2mP1f{YnBt!b;QO*L=3iIwtIFij4RTE#)2 zQ}nfjTLwG%l8>~2YabdJ*#di?^bgeM%wkIO9L-VGysQTn+5LP>dal8d z;qLNaJS&d}I+W0S)FA2g8Xr_EC1RJ}EjK10XE+_+q@WuT?al{x@8TVrEm z#hO(?xw*6lU3Aa7_jw-7>fr$BIR&6A0W(}}v-DbDUtdI2RJml836S;j^5aP{9iWv5 zJ^{hh%r(6pC=iWL5uXXGH{WWAV2!Rb)CP2hcegUxK z^O5WKcI8>{ad6Dv{O9!~Ux)nv}@5=;-Kg85tXBXLw#m0Q zs?EPV1K<6;&r>i`pohQ)bhQEI2_Dc0TY%as7y%mIjOEJW!2v=bqpVyOEg#lL@CS(8 zW@j}{PfyuyYUJhQo>5W&O$EjW_De<8#I_u;2o5)sgBg85ia~0oR99IvQ^cJM*!{ju zN3Cft2lMddmNRUG?0PzsN%%3$lbh(ZBk=%Y3-n0J&dyHq{0B3^DoWzjK?zt*j~=~f znXJO)W+d4f6h&|7&CAQv#pzHBY;G0-R4Cg&u>HnsAP13@kwM;ee~JN!1l%)AP)jQ; zAOI1_u3qfVRDmEb;ecIOQCA1CsF}W~RH5PyV%?vqblJBrW;1X`&mR5Rfq6KMOSInO zY*LkA#Btxh|2y6awDmywNoe&;CRW>GK*Oa@=$D|0iHVxb=f!7B6GGMj1nm9}`czse zwFZ(@x^zzA#Gt^}wYLK+kotgY`WT=kHiImtv*vr&0=}>3dD}%pqbm@7i?AOENm%Cb;l1 zWY?o1>1oq?KLvh z+>h1&;sWRtaB1I(cf4v@i3pc8l!^3z3CezW;H6CG3~AEO?0j{kQl8we6h^fMQDyP+ zp%JF=4rD~Ux11gw%ep=vWI1feLG=UAZ)l6?w_dWha=tWL%w^bJIr8t1m0cWBWzo21 znkcd5c67snMi0pOh7TF>Ib{+3k@{wL(Y@5+FG#7A>b7dc5ocR8-*udUa$(?5_Sc#GUPs0^G_S35&+qt*@s0Lk2~aJIJ%m!n$Ac2YXu3DD>bc+;}j4 z0s&!XqS#- zsJ}FxR!|j4XTMK|1P(n}F^|a#YQUDz>K_TE#KmGcM&*b`mpfwBA0he4PQ_7vP833! z48h3j2=C~}vcTPIlwbzV95@}XZ!>2;y-~X#eMLXT4n@&bX}0nveivb;uX{ItNz#Fr z;|ZX|Z~Kj}!lE@UCyr>h2tY^6VQc}E8!^I6x8f3q@W0k0tFt(Q#5y*?4s2{r%@?xt z4XE~iJ6>WKAh6hzYLs7NP)BVT^^j!k-#J_bT#d~@Tdf*5c8~?c-LR3NUJCJ}x|q!O z5w?hW29Ho-(4Ts}ar8{@El({m;iMB?IoZWi&hWNHIVU+PfyRl_yBAW?yUIUkrp^UZ z=h&AdM}nd??wx5-CotNVGqy5p4L9mzzBkNVL-er_ZS)QWG^%cB8gN*(JXbdFQEw8G zD74T8&7HbNp#jzPR&quAy{Xc2M${kq+GmpqXM$Jum&l+SWU)#X8NUHTprdJ#!OcO8 zSyTErRco#Nn)h}hpP4PyeU!_z^--uS>*ivMWg0S5Inim1J08YNUjBpfTAeRx~ppFKCJ6lD#mAZ`2p$ap_F+K+>~5TbJ>`%rNlMev^jOB#?fx;1)1X=*(Xw1`QZ)w#5P6yli!SHwG~PD zvPZg$G!fTBTg>Jcu~FC=y$Eir>18MMgyM`ZTui&aa*q9Pot|0=xv(Tc+NYvxD=dzChW;$(H-$HuV&d z8*3Lme*e`LtrfkP`M!C`0CtwyS~xQYRN&Qw@{{RW?o4u>3qRV&?frxa%i6v9tq(f> zFOC`ME+m-@esxJWCSTpIf4`dx7?V89MBLd(?XSoYoDzp#sb$`L6Jv)GL^51jk1y_{yfB>RXM$vrhi1;CDm&GN1YsUC!>? zTHqjwY@z>#WTm|B@!8d%&*-hiFO+E_TxLds1po_ly8U^dF|Z~>NrMV-wt@7n(8Wo? zSYI65l?Vd!)`_A5l|iun=$ME=IdT-yg!2D_~zoMqP@|MD{|h@G+FKGeMS%#(;u1_Mav~jxG-cz zXw<5J6GNofiqeO!ADpbesBgt1pLfkuZab_#s}5d7QaNLRW$>orRE-d)sx!^yt*8%s zw-xr3h;Tlr^_q6uAGg2%g$)B;h4E{0jfOueH@9EwEz{EePc-&SI9CSg29|iXk%KFhC^|r2yFXtj!A$?s0H3LU;EE1HIKtC#%#Hh7oG%Rb3R!-l z$FfWPi4SU8&X^qx?v#+}mi`G(p)v3~SCQDd3c6moqEf?a3SP%kFI~^-z{%fd`pY>7 zAEU2X8iEDmwXlIDLS z1(u1(n;1e!bKJ^)$*z+U3$BAPBg3hUpklvhh)z$p_3h3!NJPeQIU2`3PjTskbngfG z-I2#CTwjrUV#5zfKDkm)5PHd8*+j3x&CV~57S9B)sxQSc`+v&u&I@33I#?j+>Kv9N zaL%9GI><#@k~)%0`Erz9#%ZRo>3jac+hhEp!gZI6I%-F^X}0FhEKxysUtM z&7ebqG6M@QgQLitPAy+i46_fbm%Z&?C*{^a9D(&lmJIa-^9x(bw}Q}077(aeG$WfQ zX;FvtC$G-4Z*EdJMMeg2=0yC&1B;}H1YZsBmOVw?7idBM55iwi)l4PVl4_QzrY;nwTiC| zW3@k0e`xL6qoWn}2zWMtm}FO0VyK(DjzoCre#8pAq$rCguSn)3@|XWajCknv18qXw z*elr0XSNzce*K+S`k8~H>9k40K0p?%quMEdWzuONYe6V=ZQakgZ^TAEaR)Zi*x zoxwS)Jd-I@;Rw;IJmH9z`j&b)N0*nHB$~!~^mgZU!z@`hBHTV4W7aT%+eSn-itBmJ zkOj(cl5$#W(8(IKy#D=rDVH1hYE(<~!v4TyjE*h{o>KR#43v0dhn=RUa=sq&FQ4fX z)?=$#ndgZ0;WT8HD*cCL6?ex<$cdLuPTtbp^|e+yTW<;YXqLwkLwYqTEBm^KqMk%L z@oas1TB|Ex^vBx!1{4CB2rmv2Vb1F<(_C-omdRwW&MOfd_$CJ7qZ;wjou*)>)H>D~Ak&VNI8`S|4N$K>@**DxGseOhDVl=#OP zigE7L*v+Js%shhm8O05M?Xx}{&$juyr$r?Z^!G&?UI;%KuMHg)>D!_hgP+i&6&`(S zDonm`Fh*?u9V0u&YR^%7;>4_XZ(M&z1&|_7i)*PJ&cfQq5X&rT+26`2Q5QA7nVuxp z2ZQe)n(cU#`$NQK6ug#^#Z;cjcMT$#h^Q~CNib0`gC_X*6WYo~eo#pOh}N+t1Opx2 z4QMAjD)cySS+)xEx+I^Pud#gY`1h%ns&ZJ(W$-IbvFgi3rq;6idg`A|iOJZuE8!;k zZwVZlXiA@@??_rX|*L!TQJe~U;Orgw1nmvzr}ApN*@@aGH1D-A>+&A z>jYmj50UBgB~cD-rFrjaWO$oH!IWYluD8z<^bcsG+GFbW@hfXiC7E5oKH ztuF-S%w!lGtksSxGd%Ph43%N*Smyq|d=?6zFELzQOK)6nVYOa;vrap9aA zM}n=_qU)=xr7?2-yRfXI*NH5;A0@5W)L{15=w>@zAY$ANBs$@nm5!7R(NoSZx0#%z zZbv%3EzLOc*Aqi2lSL}-9vGq8Vy2JV+JecMU)0tff)cN3`LogMfVP?v;6d5BTBl7?}&aC7@PEPJmt+%l;?c?L4YSf$+ zAHbyknl>2TN5CQ=0AM_`gJLy*hle9qRvcmC^v{+fbn?$PDeuC!v7b*`!c0Se#!=(r z05DYW^XEz|!8phNfR#*Y0nd6P?B_2M>hU)K#zb)b&jcx3{tE#9?-8YgUgy$9VvoQk>EJ^rhQpPiB@N@gW z7~uFjU=IE{$MdQwA|hf?6y^DH;QCmu|GTUHF9%1~QOA?#x~sJ|94wU_a)u37U%hThy8o$! zB%tS&^?!nX>a#%d5bj-Vb*a`ndYXIY44IoSMm%wP@Q!e^_@ABz;pf2oRFh=^SKcB9 zK7x&>?L?_pR3zl*>5Pf&b;_o^dIjAU(%i=tirJXuu3nBmN#gXr0Geb|D9qk`$M0Xd z5>2e4uDEsc{Z5mk^=y;kd6H$i?(9kL%dw)!*gY2;kui7B_%Di~`(#TmAk*p%1$moq zzB$W3=xvkj@vc!6t0a~Tk{)4&P;3BC0`D=fpFV4%P_dU;SXXrYaP%Y^iMvsFL>QcDcn|jyrpJgG)jGM^7&6^J<`01iM6VXIJt=7=f zMg)audrw$qPF`}$`TT{m_!9v8V`>+?xA;1RSNPdPA2JQv=fw)x{otDG{G|*&sn7&y zRjL~8UW1n1u&a$*f?ogndl4$dC0`$qYi?Nk83+?sfwyyU?zo|@6avsKGZgKFkL>MR zONG5DY*$ek99B?;#qyXVi?XP%JdCf(l1+an~n3bv#mQ_8P4>jxZ*ApNCC4v__ugd7EHMJ zCbqaRDNA0MTu%DAeHF8JW5nA|-F1{;8$-pFWwaPx!gg7mbxjMASL#_je6RN!>Yqg~ z-nH7abz)UksqeLanIdxX(NfQ&hPw@XO$8-m^~bd{=l{;oi%r)zrf@#apZwq`MDMCU ze`PU}tw`VNbIdPdd2aJ8KKBhIdTCf~ubOFT&_8qSmb>Vg26RNm{Tn+SR&TK#bmy1)xsOJ+TFkLuZE4n`4EBu4 zjmLatAsQ<&e2VojcMNmI?!;P{)yZU~H{@QBfBb+At>m0{Z4D(otF747xVg#AkTh}0 z@gx$~dY~f<9Kn=;jN z1~plv*>TDM<0lR=E~xKrP~6?TS33eN#9(!t)&3lN|eauFct2Q)nl#bI8_nvgUUJuD=(29*?1{XlWMZQuX@7>ttF0H8GtnluZHIJkJ%#m$(%X|c zl}|fiQ{5Zz8!@^YL7wXtxHVGBIy$F)BQ5Q-UJ^U6_r4r3rb$aT*47{@TzfRFPnIH5 zMfv7XirL&46Zk8SroC8v;$Ap|8`N`=^qinsq`d33nPvD`F1SamNtfva-gzRPT8@Gx zBjzFnPjr#D#~ro^tyoo0-M2h%(HriCuimemmuu1VIX7*uIQN!uBI;d%5-jqbT;-QP ztYtTou=6XvfluZ}MQdBPW*U-fYd)2ILC2DnrA>VI`th&=KEnk zTK#6w<2L^0`ZZzMY=HOGXH2vb`rL-(jrN}El0c7PJ586it{vgS)$AuJiDkm&M%%Xm zkB=nwd4QUd{L7)2${T#b50^YAdWCFy?}~N?_3^8lHiQ4`u%WQk#+}G<7rrx-WBpKF zI8;aJ-EvvJ31O8KJO_lGWP1TBsj znI%d<;tlx%@f;C}w;GAp{_@*Pq3`3_H$7NqYwqJMuFNlOpdC?t-aNZwOi?v2i z;{iko`3uryHINxB@Nd`0zTzeV+J37HRlgg)sp{_$m+N z-hTxWAKo0kfhH+aA)&9&ojllZ`Oo7__GPlUE(Pju1UJ_)B^IB)rQct9y{umztagQ2 zFcF9_98c^*F4NLCqmtkm-TIy4CgS7g>~j?p+T)$Y}Dl)ua)+zEPvh6wk+}4#^*(*$7NH=$jA3sz9l;n zcSU_4Wmf#25gNQ7nPt0L?8eL z821xf+_viXP&O?VaarC)YhUOC)q`+ooti~4G3%5GxITu%oBPujg{0$}k zpkEbh`#3m-%*St=??|=k7s;nu26aTP?}33+r#7R0$L7#e!#nHdtGP!e)nl0O(%=NY z$;l0P+Oc}T=>s15QJPHMQnVwaNO<&RuZ7|ENXEtAK~?HqW<7TsWX?$2%?50W{4eBZ zNf#9-Cm&@2FRaYi;m8xjo}ThYY5J;}%TO5Xenc0fGyZy?@Ryl*|9~2I3SVx2kLblQ z0=>_-QSs7a#gylS>t4XHj<4aKw%v8~8NZbydGnphK^ce>bZv;cK_&w3qCYS=PS?^e zpx=vMb+9t-ihU5a6n~0{kRv5+B1Yk8HRBR)yN_4wNhspw={c-r*fnkLiw~cSc;a}h zG1h2tHap&ZA*Omo_pN?PDg~xdkr?M)Fv&KHa9kg=+!20ldf{^$We)C8OxO>nJG5+F zgeJbvVdt9tr<$slSSP)rMd;?<(|+ky*ul+-bK?xHPo?e+oE6di@~Y&)tgI~CKB z5K0S2#^?7Jd;=CA*}Y=xY8(D~!|;29XQ)?H{uKaKaT{jl2ffb?<<0;}`a8e6ctZJf zlno1T&U~7X74?0Q_TH7y_NOA>qAu|^gR$R#!e?31GEG*t7Brqt6$QSE#neZf(1>+E zT(A!9sPksKSnWPUxIH15w_<$yPgtS;N6Rb!&~BAJse~Wclz7LpD_ z|7f3ZQKx~23q@jt)A)#hO}`RDOZPjU=@iQvrP!oQZT1B8{}2u&YgjOjq>7@ld7R&Z zE$rFsQH}Zpc0<%=ji*$j*O@Ca*&FhE-$qC4zo-s> zgkW9HCjaB{m`YavKjb3pTNufjLTg#A<`P00qI47H<@QZv{)xzDxP;l+*#Wu}kiVbo z7=ZHArVXoY-i1Mc+){XZjBq0mTT19)XX<+}B9HR|1vS2CWya(ZaxZrTXu#rWb^CO%eoe_QU^|8xiYdb9G_Lp@r#OqL#Vd^f+tL)NO)wQcdMJZb_daD|=po z%f!X_FExu$`czXUi4h<%DkL8Zb`Fd3vbO;zIak zoDVvO``WrS{2LE_o-OUhcqDDQy{FJa#r2zmtGJ|AwWHDqk3Btq_G?RSBQAW0l^>y~ z`3eAyd~{6Mo$8D)^SeYAr>z7zMKWh}`3z+@_nzmPeJ2v^##BuDgFdZ@NV@xx$cI4? zP$Yxgk3(55V*94d`_;(#_M>EP>BB9?Kee{KPQq$&50A)YEu6v55KLdxrC?D>b+GOI z{NnJ=qawV_+&NX*lcQKn!65V?MO0hW`b+-ML$S^oGsVHe%F*m#rYObt#pTx+zLp%K z!VRxlgi%1`t`TT4RuMu9ja_jg(ISK8)7x~$8ll@E?X>;^`Vu$rU5pl91fnhnlQ+HaDk3D(d`xp)J)1KEf`3O90 zw$e&tPh+5-7=zH2MsSWKsnt{+Jikn4H)awX+2q7Fk7{~c0BUL^3y-1$J&7qHx#oqV z8k`oWXT6H(xm#IWT#}h<3GGY9ge6`sa+@RRE*+4~5``ZP_jqgi@6HucY(qkxmAHem zxvZh0+6?Lwim8K&W4Z9DjFK?gBr=S)fDjcP1&;!&xq`TKiAUMSErCj$u!XO|Z6f#V z8$C7}f)D*eb>N$sD(hhzLI)KqV&RDOgzQ0$$Eh?gUhZhAx@Ac6XIB*uoSaCjw7?*` ziXRLV(~jsB8Z2}(88%fhb!PB*5N|C9u~9d?5-VSlW6b=ku8wmb;y#hyX;sIRyD~eL zBgIZ5J|lVdqQe|4Z8eH5Aqv%7uf-u7y0XYpLWfw`tivg1Dl47mVnn7I3%;&)oFO~c zY8tyH&LvV+73p8Yl^67wmp!JAox@%(>gjXC2%4&?sn3An*BFG-R2Dl9_7-T;a9Q*l ztKi5C$IR^u?~Id?<>7qRT{s?h0~BtQJGI{nriZOCh3E#Wv{NQko^_p<7-~e?W4NtG zf+>Q@tc2~7ITT$fvmk+4BMm_i)2ih>*Shkyi$UjbPZaCb&zF=H_b_WgLvRoLwJt+7_I_`g6_S8R^Makj;T?@!kXMOwg z8yG04b1#6Gcmp4acXN>RYco=?O{$zO8}>D`VR)EF_?Tut?i9ZKBX}6~tSIp6YXbBUz$)X=n>T@{Ev~KU3O0XKi{Cq z{Y{KMrGXot!+p1WXsw{#CkSsGh0|)yVq8-SpS`)hggi`j#qF86CL2viZ2IB3Wp&c1 z8hNM9arWKuvOw7#c4*zjFKgtiuBqkMeIf13EX^{85ix$=OzPQym;ZsnJ#}a9$@KL4 z7gJ!Q$5Q}$xq$f-J*Ad5<%Eh7F*&Z zRm*r!wcb0E;~kVHSewGh(v))auqpdu7Q4>F@pvDaJA#9v*T+0@XGG;2!_p~nG1w^F z%kcc%$2T}m4)8CwR*C4>Yuy+p7<^=cme6$Wzb)-^>a`xF#~vf!Y2MGiBFqxx)7ZHH zV~`v*1V)=Cs^*o;oSC|`df8KtG4e%NOLOn?soOm=(+DY<9DZ59Srq<3Q5Ur4-TbP2 z{D!?GH1&=LB<6&$c)Wk|7B8S<@9AxTPgXxSNDXBDN+G%yp7^Y2)$$)MxSZqOLY=Ll zqR+8CK;~6Vv5fq2%=>iP#y+dR{qoWF^6k7TC%A!GH0Wc+{xuCVj&J@UmizzH)Kv#G z_4RKN>5?xYjfixEbSfes0s>MBIGi*xdNhb4Dh&c6F_DrUCEZ93Ho7~d89fH_-of{M zf4}qZ&bjy8bIJ3=hp8RSNqA1S<2%NOp&Tgpdi@KLd4`wT0g-rW<jS|jXcHy{6fjvcIa^KUS(Pxz|yj-&u|1fSA3 zMi<*u4hF2#5@J?L-P~xa@6%KbEjHjz-KA55HF*O7IS3RFjnzUST`mB{0|y7k2^PD! zzW%w_dht(x#zQqVYM_3IKZ8r3b%H$LebElma^b6=sHxrloWa3yO(|IF6hT8SyUSf1 z{z7e^C|hj#F}cYFC0oO)bc==emv~B1$+gy#MrhUdxlr8q$!wOtK2uawH2M<_53tD1 z0O-JLDMtOLaq*1WBo80jcYofw#49;7R^nqVa%s!EvgRiMYCXY)0L4yh zZ?d!jP#*7!1f;I<@Cp0seW8F3AcKT8`Czs-r}E3?LEOqbTxvHeL;BHTPdQb{o zt<-dGLJ*G6tkTIG(6+>2R$&N7nwvLOo<6;Ktrof?eAoxR@*0`-;t?&iRaK$^XI?l3 z=*Gstq&MHB-gE;y29KAQ7c^btVaWR5#W7wcHwHikTGtD6U;*C%nbl7Kk7-;|k|xk= zZLEaT91ugXYqTHcr$byN&Mrs{DXRea+0T`g0F3ycd3-#HP0^<>Lp@4-5$xO6eN|L`?68V!otGX>dB>dtqElIzQh7zm(A~p02D;c zIvCIm1vYPIclRA&?Dy}t?S}`H4S?m>ceB$>|M38iYEQ3TQ{s<}IPw5{iDJh6@=az{A&iiSEa8~f~%tM`9^r>Rliu8!$ zr0Xvfe2?4X42WgC2g+3?)~#7Vs~pT0LaMe47E^|nco^@TP90^P2WI@^w{j6K7+Ksu zz^swh*<2En$&XKwEGl%@I}k>k_e{|4($4&oANn^xof zij1PKZup;t1#oSt-!Un7=87R&=<3Xm2n|#}RTO{AQD`0}=X|%sLr;b*Q0C!>)+ZS+ z2>XkX%ZaK?<^?B1W%TT(Xbj?}&!aPqhkoL7h7BcJvdw8$?4`Td`nH_qpx?>#m6SFI zADvDZ@j6gF0e|rABhKa1VqVfP!XEoXehN|w1nU`R*MBk9j_bimVmq_ zIVnFAijAiEEaWBNuW@^SMLP}0`97k|$|?rSJ zvO%rE&^Vnb%&rL`L81r6vdzy8&FSYk8lN=VD@?%!X~K8!uB5$r`W2CD#+gRJJeNSP z?rEAzyAm7Y9R50#COW9XjyZUpj=+vcm?;ytPlldILR)nrzUU61!c2E(Ia7-4jdNl@ zYRMk24C(y3@PERj99`s5CX<$Qe=jC(3^6`^>5yid>0cnirIl7qHeB8dnY6@K7mK&~ z3$SY^s}I>VQMVdP%-U#e;XT3ZY9)wxMUfOPVC+|>e(bBX2hM^=e2AuD$*5S}mLzuv z(hX_u1guZkSl7qTAob58sd98gvC9ltGg;6-!%QG*RXje67L?JtJizh)1<_n;lMp|O7WkK4uh4Rf;NGWR3>$O`{& zZ~}yB1BiQZvJE}#ix_|T6kWU_h|hMot}h^+deB2YP?qX^c+i&hEEu8V<4Wjh3^`j* z?(Vl?W9(X6(kCmcWz0cb1YI70KgdT7jal5$PqW0$0dv^Vq9RyQj|aUj{@&L-@YT79 zdM6xzt+C{6`l56{T0qEYD{L(^R{>+C_`v5l<6?{B#QYUp!uOYOmcpBEPH%%7wGJN3 z)mV9ue^VzfGyI`h>9p?KeZVxj+*U77-zVE+-_8&oDa7z?#us_dO z(xhOWoH1u3dzxveR=~_>b3Zi_yipobfRT(`8dRILow554X7l7tgONBW z?vyEm0WK7kB2FstMGd6b{G$2sruV2y%>jRR)z&B7_Ot^bk+Z`|vJXyiuCWq>4>C5jg*AO^-DXJ=JlKYR#+Y4Ki?Rc=|G(3Tr=v&-> zHKH2KcXeiv*|Yn^w#?zs0SJo)mR|RKBGRH>9;|(uq>bGt{xe1bGhwby{8OD&D;`kVczzSpRKX~d?-Ya5k{vBfyIJh z9|CU3vA*t^M3@Fbc~yB=$J8XOSJjJeHZ;=cDjW+cp7#c&7D6aF3lMq*$ zu^zz#a<3Dq^t2ovVa-oj&*gQvqraF&CD$=Kug7lOi10c!$<KKIPBCR z+prUhZb>i3_nzJMYo;FVnVQQimH>c1uCc7%X~fF44mg{b+g4SgDkol9HW0e z=cDTyQtTJ!H=VmK3Dr_NoD`p3*YIMcC6i?phU-UcE!g?UPcqdm}9 z{TDF{9{+H#9biV`y2ik_&*^^dV2BPFwiP`qyAx}Jyg%T3ZnqYlbx zBYD_G4q?5NGnF&(oFHDUeiGljt-SSz~s1O5`2e&JRfPFJvx|4dJG#I;&pK<<{)hGILmYJV%*U zM9xF%l56^wxx2-VWXajQUXXR3EJ`ov;QwNfLcK%=B+88q4$A7KMRoPXT2x|U;ht;` zl-3}G0uq_!b^;pSS*i|FuYBw7K7q6$3*={N4G2~YdpX~=stiK>?taRK2{!(#l;q7! z1DCxP8qwO1ex2mEd&G;%?EY$vc75=|n%ib^=|QQEH5gh7I;?Yk2eP!j^N9!XSaqa5 zBVDASfg*QRU&Yf^5KDEJ-li9~&Q5|l{@5cScURYzuC>kH)9T{l%$AlG{bCf$En3|FK$$vWqzHv|o8I#I;w2pJ5|99U3{Wlo(%khNMcdl}#B< zgLIB^X2(e$(PSS8S~PErAva?rI++f|44j}sd@hadgUw}D^Xh3r^G@>R-_*j4Z+eTy zDTI67@U)uyNqs=&PT=VHRW6p`FdJ^`7rKyNN^{ZL(et7t;?GIk7zMq8lf70WwnO}G zrf^~@09@Y-L>cSZ+Wx6X!@;06vUun6(g!j)P0(AqZKFHg^~Y11VX-|Sso^h2OZ24-?KsjmM#uA8$@pMimt7DT!m(ouN=1 ztowgIE1KQW{}FJ0nh0@^H;=lsrTIjFQb_$41cD3-J$6ux_-A{2+soVAe8Ucy)5mAu z0H`w`7ccLh8seI%>1h&D(wdP$oEw@OOR9V_<|wu3EYsOrKLmDH%goL*%%=y`8gYp8 zp`mB4uC7JTIVj#W2aP*s12^q<1dPZ|iu4w|QNRzD^*a$2FfOY5XP-J|<9%XcVldmK zH<$N|D@0gW_+V%DBF|6;S0w~gN6Z+?w0el)kmf)T00?O$2%A68TdKv)@MGu25Bo0X z!?nRs9P+piP}cZB$?DVpB(dMNAd=(XWUQ|t(ixyT6azH{>F;=KPcicF@FWPD>hljS z&(AlHm4GpT8j;46Ck5+$qglYKG2h_3x;Pyz6VvnUUxuVr3JMAgvaYX_#tS6kWN6$a zourx-W>3otuKe(&NB`%CS6kyHhK3SRFx{&%`fsGfC0_WOW#uG5 zdr&wq2WWi&ugWl&>S`VvhFSPU0EGeYQOLV@Qca}>@NWXGy8jvf-1>0-Ek)m>f&>y^ zgc!Iz+bs-P$Wf&#ea s%2{h|_-~Hf$^E~O`lA0;`xVEsiyO==m9ABKe Date: Wed, 1 Jul 2020 08:22:23 +0200 Subject: [PATCH 6/6] state_overrides: Also fully support hosts --- application/forms/AddNodeForm.php | 45 +++++++++++++++++++++++++++--- application/forms/EditNodeForm.php | 43 +++++++++++++++++++++++++++- doc/07-State-Overrides.md | 2 +- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php index 11f24f3..df9fe66 100644 --- a/application/forms/AddNodeForm.php +++ b/application/forms/AddNodeForm.php @@ -200,6 +200,11 @@ class AddNodeForm extends QuickForm ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); + + $this->addHostOverrideCheckbox(); + if ($this->getSentValue('host_override') === '1') { + $this->addHostOverrideElement(); + } } protected function selectService() @@ -258,6 +263,25 @@ class AddNodeForm extends QuickForm ]); } + protected function addHostOverrideCheckbox() + { + $this->addElement('checkbox', 'host_override', [ + 'ignore' => true, + 'class' => 'autosubmit', + 'label' => $this->translate('Override Host State'), + 'description' => $this->translate('Enable host state overrides') + ]); + } + + protected function addHostOverrideElement() + { + $this->addElement('stateOverrides', 'stateOverrides', [ + 'required' => true, + 'label' => $this->translate('State Overrides'), + 'states' => $this->enumHostStateList() + ]); + } + protected function addServiceOverrideCheckbox() { $this->addElement('checkbox', 'service_override', [ @@ -396,6 +420,17 @@ class AddNodeForm extends QuickForm return $res; } + protected function enumHostStateList() + { + $hostStateList = [ + 0 => $this->translate('UP'), + 1 => $this->translate('DOWN'), + 99 => $this->translate('PENDING') + ]; + + return $hostStateList; + } + protected function enumServiceList($host) { $names = $this->backend @@ -501,19 +536,21 @@ class AddNodeForm extends QuickForm { $changes = ProcessChanges::construct($this->bp, $this->session); switch ($this->getValue('node_type')) { + case 'host': case 'service': $stateOverrides = $this->getValue('stateOverrides'); if (! empty($stateOverrides)) { - $services = []; + $childOverrides = []; foreach ($this->getValue('children') as $service) { - $services[$service] = $stateOverrides; + $childOverrides[$service] = $stateOverrides; } $changes->modifyNode($this->parent, [ - 'stateOverrides' => array_merge($this->parent->getStateOverrides(), $services) + 'stateOverrides' => array_merge($this->parent->getStateOverrides(), $childOverrides) ]); } - case 'host': + + // Fallthrough case 'process': if ($this->hasParentNode()) { $changes->addChildrenToNode($this->getValue('children'), $this->parent); diff --git a/application/forms/EditNodeForm.php b/application/forms/EditNodeForm.php index 98596e5..588c6de 100644 --- a/application/forms/EditNodeForm.php +++ b/application/forms/EditNodeForm.php @@ -182,6 +182,14 @@ class EditNodeForm extends QuickForm 'description' => $this->translate('The host for this business process node'), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] )); + + $this->addHostOverrideCheckbox(); + $hostOverrideSent = $this->getSentValue('host_override'); + if ($hostOverrideSent === '1' + || ($hostOverrideSent === null && $this->getElement('host_override')->isChecked()) + ) { + $this->addHostOverrideElement(); + } } protected function selectService() @@ -218,6 +226,27 @@ class EditNodeForm extends QuickForm $this->getElement('hosts')->setValue($this->host); } + protected function addHostOverrideCheckbox() + { + $this->addElement('checkbox', 'host_override', [ + 'ignore' => true, + 'class' => 'autosubmit', + 'value' => ! empty($this->parent->getStateOverrides($this->node->getName())), + 'label' => $this->translate('Override Host State'), + 'description' => $this->translate('Enable host state overrides') + ]); + } + + protected function addHostOverrideElement() + { + $this->addElement('stateOverrides', 'stateOverrides', [ + 'required' => true, + 'states' => $this->enumHostStateList(), + 'value' => $this->parent->getStateOverrides($this->node->getName()), + 'label' => $this->translate('State Overrides') + ]); + } + protected function addServicesElement($host) { $this->addElement('select', 'children', array( @@ -351,6 +380,17 @@ class EditNodeForm extends QuickForm return $res; } + protected function enumHostStateList() + { + $hostStateList = [ + 0 => $this->translate('UP'), + 1 => $this->translate('DOWN'), + 99 => $this->translate('PENDING') + ]; + + return $hostStateList; + } + protected function enumServiceList($host) { $names = $this->backend @@ -447,6 +487,7 @@ class EditNodeForm extends QuickForm $changes->deleteNode($this->node, $this->parent->getName()); switch ($this->getValue('node_type')) { + case 'host': case 'service': $stateOverrides = $this->getValue('stateOverrides') ?: []; if (! empty($stateOverrides)) { @@ -460,7 +501,7 @@ class EditNodeForm extends QuickForm } $changes->modifyNode($this->parent, ['stateOverrides' => $stateOverrides]); - case 'host': + // Fallthrough case 'process': $changes->addChildrenToNode($this->getValue('children'), $this->parent); break; diff --git a/doc/07-State-Overrides.md b/doc/07-State-Overrides.md index 0905346..dfdbaeb 100644 --- a/doc/07-State-Overrides.md +++ b/doc/07-State-Overrides.md @@ -2,7 +2,7 @@ Business processes utilize their children's states to calculate their own state. While you can influence this with [operators](09-Operators.md), it's also possible -to override individual states. (Currently this applies only to service nodes.) +to override individual states. (This applies to host and service nodes.) ## Configuring Overrides