Compare commits

..

28 Commits

Author SHA1 Message Date
v-dumas
ba05da4a17 N°8994 -Add description on all iTop classes FR 2026-02-09 14:37:29 +01:00
v-dumas
b3a1565771 N°8994 -Add description on all iTop classes 2026-02-09 14:34:17 +01:00
v-dumas
ffe98a6649 N°8994 - Add description on iTop classes (5) 2026-02-09 11:00:40 +01:00
Vincent Dumas
b42f5566ba Update datamodels/2.x/itop-config-mgmt/dictionaries/en.dict.itop-config-mgmt.php
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2026-02-09 11:00:40 +01:00
v-dumas
ee0c65d81b N°8994 - Add description on iTop classes (4) 2026-02-09 11:00:37 +01:00
v-dumas
29736d794b N°8994 - Add description on all iTop classes (2) 2026-02-09 11:00:25 +01:00
v-dumas
7ea4aa4cea N°8994 - Add classes description (part2) 2026-02-09 11:00:17 +01:00
v-dumas
32778eeea0 N°8994 - Add classes description (part1) 2026-02-09 10:59:42 +01:00
Eric Espie
a5dededfb4 Merge remote-tracking branch 'origin/support/3.2' into develop 2026-02-05 17:06:26 +01:00
Eric Espie
4f878536a8 Fix CI 2026-02-05 16:53:02 +01:00
Eric Espie
d937ec0350 Fix CI 2026-02-05 16:24:27 +01:00
Eric Espie
1cdcaac3d0 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	sources/Core/Kpi/KpiLogData.php
2026-02-05 15:33:25 +01:00
Eric Espie
985db46960 N°9193 - Start the KPI logs at the beginning of the http request 2026-02-05 14:57:54 +01:00
v-dumas
01adaadfad N°8492 - Missing accent for 'Categorie' 2026-02-02 14:56:53 +01:00
Molkobain
3f807a64bb N°9154 - Update Jimmy avatar to reduce size 2026-01-28 11:54:56 +01:00
Molkobain
1d4a155e8f N°9154 - Add Amine, Gaëlle & Lorraine to sample data 2026-01-28 11:53:23 +01:00
v-dumas
643752f8e7 N°8378 - Missing rights on incident for SuperUser 2026-01-23 16:24:19 +01:00
v-dumas
0e0c09c420 N°9027 - Add right on WorkOrder transition to SuperUser 2026-01-23 15:55:59 +01:00
v-dumas
2b6fa8b381 N°9080 - Fix duplicate 'Model' in class labels in EN and FR 2026-01-23 15:07:49 +01:00
v-dumas
7d2dc5e36a N°9076 - Fix typos and cosmetics in FR initial queries 2026-01-23 14:36:38 +01:00
v-dumas
f87df8f28b N°9087 - Add logo on Brand and OS Family, with structural data 2026-01-21 17:13:32 +01:00
Anne-Cath
cc9e64616f N°8786 - configuration: allow conditions on the allowed_login_types field - cleanup 2026-01-16 16:29:15 +01:00
Stephen Abello
f34373be6d N°7909 - Missing spacing between fields when columns collapse 2026-01-16 15:30:32 +01:00
v-dumas
a39234f438 N°4032 - Restore explicit dependency used in filter 2026-01-14 16:06:14 +01:00
v-dumas
ac8937105d N°8873 - Modify Tooltip on 'filter' field of TriggerOnObjectUpdate class 2026-01-12 16:33:36 +01:00
odain
fb6f892244 N°9085 - Cannot install itop without a portal 2026-01-12 15:43:56 +01:00
v-dumas
0a04c83c7b N°9045 - Add a tooltip for Service Family in Service details 2026-01-12 15:20:14 +01:00
v-dumas
cc8252bebf N°9046 - Tooltip mentions that a team is required on a support model 2026-01-12 14:52:57 +01:00
226 changed files with 4495 additions and 23655 deletions

View File

@@ -5,9 +5,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\Dashboard\Layout\DashboardLayoutGrid;
use Combodo\iTop\Application\Dashlet\DashletFactory;
use Combodo\iTop\Application\Dashlet\Service\DashletService;
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
@@ -15,12 +12,9 @@ use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\DesignDocument;
use Combodo\iTop\DesignElement;
use Combodo\iTop\PropertyType\PropertyTypeDesign;
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
require_once(APPROOT.'application/dashlet.class.inc.php');
require_once(APPROOT.'core/modelreflection.class.inc.php');
/**
@@ -30,7 +24,7 @@ require_once(APPROOT.'core/modelreflection.class.inc.php');
*/
abstract class Dashboard
{
/** @var string $sTitle */
/** @var string $sTitle*/
protected $sTitle;
/** @var bool $bAutoReload */
protected $bAutoReload;
@@ -40,7 +34,7 @@ abstract class Dashboard
protected $sLayoutClass;
/** @var array $aWidgetsData */
protected $aWidgetsData;
/** @var DesignElement|null $oDOMNode */
/** @var \DOMNode|null $oDOMNode */
protected $oDOMNode;
/** @var string $sId */
protected $sId;
@@ -49,11 +43,6 @@ abstract class Dashboard
/** @var \ModelReflection $oMetaModel */
protected $oMetaModel;
/** @var array Array of dashlets with position */
protected array $aGridDashlets = [];
protected $oDashletFactory;
/**
* Dashboard constructor.
*
@@ -68,7 +57,6 @@ abstract class Dashboard
$this->aCells = [];
$this->oDOMNode = null;
$this->sId = $sId;
$this->oDashletFactory = DashletFactory::GetInstance();
}
/**
@@ -80,7 +68,7 @@ abstract class Dashboard
{
$this->aCells = []; // reset the content of the dashboard
set_error_handler(['Dashboard', 'ErrorHandler']);
$oDoc = new PropertyTypeDesign();
$oDoc = new DOMDocument();
$oDoc->loadXML($sXml);
restore_error_handler();
$this->FromDOMDocument($oDoc);
@@ -89,15 +77,10 @@ abstract class Dashboard
/**
* @param \DOMDocument $oDoc
*/
public function FromDOMDocument(DesignDocument $oDoc)
public function FromDOMDocument(DOMDocument $oDoc)
{
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
if ($this->oDOMNode->getElementsByTagName('cells')->count() === 0) {
$this->FromDOMDocumentV2($oDoc);
return;
}
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0)) {
$this->sLayoutClass = $oLayoutNode->textContent;
} else {
@@ -138,7 +121,7 @@ abstract class Dashboard
$aDashletOrder = [];
/** @var \DOMElement $oDomNode */
foreach ($oDashletList as $oDomNode) {
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
if ($oRank) {
$iRank = (float)$oRank->textContent;
}
@@ -164,39 +147,7 @@ abstract class Dashboard
}
/**
* @param \DOMDocument $oDoc
*/
public function FromDOMDocumentV2(DesignDocument $oDoc)
{
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
$this->sLayoutClass = DashboardLayoutGrid::class;
$this->sTitle = $this->oDOMNode->GetChildText('title', '');
$iRefresh = intval($this->oDOMNode->GetChildText('refresh', '0'));
$this->bAutoReload = $iRefresh > 0;
$this->iAutoReloadSec = $iRefresh;
$oDashletsNode = $this->oDOMNode->GetUniqueElement('pos_dashlets');
$oDashletList = $oDashletsNode->getElementsByTagName('pos_dashlet');
foreach ($oDashletList as $oPosDashletNode) {
$aGridDashlet = [];
$aGridDashlet['position_x'] = intval($oPosDashletNode->GetChildText('position_x', '0'));
$aGridDashlet['position_y'] = intval($oPosDashletNode->GetChildText('position_y', '0'));
$aGridDashlet['width'] = intval($oPosDashletNode->GetChildText('width', '2'));
$aGridDashlet['height'] = intval($oPosDashletNode->GetChildText('height', '1'));
$oDashletNode = $oPosDashletNode->GetUniqueElement('dashlet');
$sId = $oPosDashletNode->getAttribute('id');
$oDashlet = $this->InitDashletFromDOMNode($oDashletNode);
$oDashlet->SetID($sId);
$aGridDashlet['dashlet'] = $oDashlet;
$this->aGridDashlets[] = $aGridDashlet;
}
}
/**
* @param DesignElement $oDomNode
* @param \DOMElement $oDomNode
*
* @return mixed
*/
@@ -209,7 +160,7 @@ abstract class Dashboard
// Test if dashlet can be instantiated, otherwise (uninstalled, broken, ...) we display a placeholder
$sClass = static::GetDashletClassFromType($sDashletType);
/** @var \Dashlet $oNewDashlet */
$oNewDashlet = $this->oDashletFactory->CreateDashlet($sClass, $sId);
$oNewDashlet = new $sClass($this->oMetaModel, $sId);
$oNewDashlet->SetDashletType($sDashletType);
$oNewDashlet->FromDOMNode($oDomNode);
@@ -253,31 +204,18 @@ abstract class Dashboard
*/
public function ToXml()
{
$oMainNode = $this->CreateEmptyDashboard();
$this->ToDOMNode($oMainNode);
$sXml = $oMainNode->ownerDocument->saveXML();
return $sXml;
}
/**
* @return DesignElement
* @throws \DOMException
*/
public function CreateEmptyDashboard(): DesignElement
{
$oDoc = new DesignDocument();
$oDoc = new DOMDocument();
$oDoc->formatOutput = true; // indent (must be loaded with option LIBXML_NOBLANKS)
$oDoc->preserveWhiteSpace = true; // otherwise the formatOutput option would have no effect
/** @var DesignElement $oMainNode */
$oMainNode = $oDoc->createElement('dashboard');
$oMainNode->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$oMainNode->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
$oDoc->appendChild($oMainNode);
return $oMainNode;
$this->ToDOMNode($oMainNode);
$sXml = $oDoc->saveXML();
return $sXml;
}
/**
@@ -341,7 +279,7 @@ abstract class Dashboard
}
$this->sTitle = $aParams['title'];
$this->bAutoReload = $aParams['auto_reload'] == 'true';
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$aParams['auto_reload_sec']);
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
foreach ($aParams['cells'] as $aCell) {
$aCellDashlets = [];
@@ -349,7 +287,7 @@ abstract class Dashboard
$sDashletClass = $aDashletParams['dashlet_class'];
$sId = $aDashletParams['dashlet_id'];
/** @var \Dashlet $oNewDashlet */
$oNewDashlet = $this->oDashletFactory->CreateDashlet($sDashletClass, $sId);
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
if (isset($aDashletParams['dashlet_type'])) {
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
}
@@ -367,11 +305,7 @@ abstract class Dashboard
public function Save()
{
}
public function PersistDashboard(string $sXml): bool
{
return true;
}
/**
@@ -569,7 +503,7 @@ EOF
{
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
/** @var \DashboardLayout $oLayout */
/** @var \DashboardLayoutMultiCol $oLayout */
$oLayout = new $this->sLayoutClass();
foreach ($this->aCells as $iCellIdx => $aDashlets) {
@@ -579,13 +513,7 @@ EOF
}
}
if (count($this->aCells) > 0) {
$aDashlets = $this->aCells;
} else {
$aDashlets = $this->aGridDashlets;
}
$oDashboard = $oLayout->Render($oPage, $aDashlets, $bEditMode, $aExtraParams);
$oDashboard = $oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
$oPage->AddUiBlock($oDashboard);
$bFromDasboardPage = isset($aExtraParams['from_dashboard_page']) ? isset($aExtraParams['from_dashboard_page']) : false;
@@ -675,12 +603,29 @@ JS
* Return an array of dashlets available for selection.
*
* @return array
* @throws \Combodo\iTop\Application\Dashlet\DashletException
* @throws \DOMFormatException
* @throws \ReflectionException
*/
protected function GetAvailableDashlets(): array
protected function GetAvailableDashlets()
{
return DashletService::GetInstance()->GetAvailableDashlets();
$aDashlets = [];
foreach (get_declared_classes() as $sDashletClass) {
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, ['DashletUnknown', 'DashletProxy'])) {
$oReflection = new ReflectionClass($sDashletClass);
if (!$oReflection->isAbstract()) {
$aCallSpec = [$sDashletClass, 'IsVisible'];
$bVisible = call_user_func($aCallSpec);
if ($bVisible) {
$aCallSpec = [$sDashletClass, 'GetInfo'];
$aInfo = call_user_func($aCallSpec);
$aDashlets[$sDashletClass] = $aInfo;
}
}
}
}
return $aDashlets;
}
/**
@@ -695,7 +640,6 @@ JS
$iNewId = max($iNewId, (int)$oDashlet->GetID());
}
}
return $iNewId + 1;
}
@@ -730,7 +674,6 @@ JS
if (is_subclass_of($sType, 'Dashlet')) {
return $sType;
}
return 'DashletUnknown';
}
@@ -783,8 +726,6 @@ class RuntimeDashboard extends Dashboard
{
parent::__construct($sId);
$this->oMetaModel = new ModelReflectionRuntime();
$this->oDashletFactory->SetModelReflectionRuntime($this->oMetaModel);
ServiceLocator::GetInstance()->RegisterService('ModelReflection', $this->oMetaModel);
$this->bCustomized = false;
}
@@ -799,7 +740,6 @@ class RuntimeDashboard extends Dashboard
/**
* @param bool $bCustomized
*
* @since 2.7.0
*/
public function SetCustomFlag($bCustomized)
@@ -824,26 +764,6 @@ class RuntimeDashboard extends Dashboard
public function Save()
{
$sXml = $this->ToXml();
return $this->PersistDashboard($sXml);
}
/**
* @param string $sXml
*
* @return bool
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
public function PersistDashboard(string $sXml): bool
{
$oUDSearch = new DBObjectSearch('UserDashboard');
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
@@ -864,7 +784,6 @@ class RuntimeDashboard extends Dashboard
utils::PushArchiveMode(false);
$oUserDashboard->DBWrite();
utils::PopArchiveMode();
return $bIsNew;
}
@@ -1158,7 +1077,6 @@ JS
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
$sActionEditId = "ibo-dashboard-menu-edit-{$sId}";
$sPopoverMenuId = "ibo-dashboard-menu-popover-{$sId}";
$sName = 'UI:Dashboard:Actions';
@@ -1172,21 +1090,6 @@ JS
} else {
$oToolbar = $oDashboard->GetToolbar();
}
// TODO 3.3 Check if we need different action for custom dashboard creation / edition
$oActionEditButton = ButtonUIBlockFactory::MakeIconAction(
'fas fa-pen',
$this->HasCustomDashboard() ? Dict::S('UI:Dashboard:EditCustom') : Dict::S('UI:Dashboard:CreateCustom'),
$sActionEditId,
'',
false,
$sActionEditId
)
->AddCSSClass('ibo-top-bar--toolbar-dashboard-edit-button')
->AddCSSClass('ibo-action-button');
$oToolbar->AddSubBlock($oActionEditButton);
$oActionButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', Dict::S($sName), $sName, '', false, $sMenuTogglerId)
->AddCSSClass('ibo-top-bar--toolbar-dashboard-menu-toggler')
->AddCSSClass('ibo-action-button');
@@ -1196,8 +1099,8 @@ JS
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
$sJSExtraParams = json_encode($aExtraParams);
if ($this->HasCustomDashboard()) {
// $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
// $aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
$oRevert = new JSPopupMenuItem(
'UI:Dashboard:RevertConfirm',
Dict::S('UI:Dashboard:DeleteCustom'),
@@ -1205,8 +1108,8 @@ JS
);
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
} else {
// $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
// $aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
}
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
@@ -1320,7 +1223,7 @@ EOF
$sId = json_encode($this->sId);
$sLayoutClass = json_encode($this->sLayoutClass);
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string)$this->iAutoReloadSec;
$sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = json_encode($this->sTitle);
$sFile = json_encode($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
@@ -1492,11 +1395,19 @@ JS
// Get the list of possible dashlets that support a creation from
// an OQL
$aAllDashlets = DashletService::GetInstance()->GetAvailableDashlets();
$aDashlets = [];
foreach ($aAllDashlets as $sDashletClass => $aInfo) {
if ($aInfo['can_create_by_oql']) {
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
foreach (get_declared_classes() as $sDashletClass) {
if (is_subclass_of($sDashletClass, 'Dashlet')) {
$oReflection = new ReflectionClass($sDashletClass);
if (!$oReflection->isAbstract()) {
$aCallSpec = [$sDashletClass, 'CanCreateFromOQL'];
$bShorcutMode = call_user_func($aCallSpec);
if ($bShorcutMode) {
$aCallSpec = [$sDashletClass, 'GetInfo'];
$aInfo = call_user_func($aCallSpec);
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
}
}
}
}
@@ -1506,7 +1417,7 @@ JS
$oSubForm = new DesignerForm();
$oMetaModel = new ModelReflectionRuntime();
/** @var \Dashlet $oDashlet */
$oDashlet = DashletFactory::GetInstance()->CreateDashlet($sDashletClass, 0);
$oDashlet = new $sDashletClass($oMetaModel, 0);
$oDashlet->GetPropertiesFieldsFromOQL($oSubForm, $sOQL);
$oSelectorField->AddSubForm($oSubForm, $aDashletInfo['label'], $aDashletInfo['class']);
@@ -1660,7 +1571,7 @@ JS
*/
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
{
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
if (!$bIsDashletWithListPref) {
return;
}
@@ -1708,7 +1619,6 @@ JS
//on error, return default value
return null;
}
return DataTableSettings::GetAppUserPreferenceKey($aClassAliases, $sDataTableId);
}
}

View File

@@ -30,7 +30,7 @@ use Combodo\iTop\Application\WebPage\WebPage;
*/
abstract class DashboardLayout
{
abstract public function Render($oPage, $aDashlets, $bEditMode = false, array $aExtraParams = []);
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
/**
* @param int $iCellIdx
@@ -43,8 +43,8 @@ abstract class DashboardLayout
public static function GetInfo()
{
return [
'label' => '',
'icon' => '',
'label' => '',
'icon' => '',
'description' => '',
];
}
@@ -74,7 +74,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
}
$idx++;
}
return $aDashlets;
}
@@ -95,7 +94,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
}
$idx++;
}
return $aCells;
}
@@ -111,8 +109,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
// Trim the list of cells to remove the invisible/empty ones at the end of the array
$aCells = $this->TrimCellsArray($aCells);
// TODO 3.3 Handle dashboard new format, convert old format if needed
$oDashboardLayout = new DashboardLayoutUIBlock($aExtraParams['dashboard_div_id']);
$oDashboardLayout = new DashboardLayoutUIBlock();
//$oPage->AddUiBlock($oDashboardLayout);
$iCellIdx = 0;
@@ -120,16 +117,15 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
//Js given by each dashlet to reload
$sJSReload = "";
$oDashboardGrid = new \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardGrid();
$oDashboardLayout->SetGrid($oDashboardGrid);
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
$oDashboardRow = new DashboardRow();
//$oDashboardLayout->AddDashboardRow($oDashboardRow);
$oDashboardLayout->AddDashboardRow($oDashboardRow);
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
$oDashboardColumn = new DashboardColumn($bEditMode);
$oDashboardColumn->SetCellIndex($iCellIdx);
//$oDashboardRow->AddDashboardColumn($oDashboardColumn);
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
if (array_key_exists($iCellIdx, $aCells)) {
$aDashlets = $aCells[$iCellIdx];
@@ -137,18 +133,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
/** @var \Dashlet $oDashlet */
foreach ($aDashlets as $oDashlet) {
if ($oDashlet::IsVisible()) {
$sDashletId = $oDashlet->GetID();
$sDashletClass = get_class($oDashlet);
$aDashletDenormalizedProperties = $oDashlet->GetDenormalizedProperties();
// $aDashletsInfo = $sDashletClass::GetInfo();
//
// // TODO 3.3 Gather real position and height/width if any.
// // Also set minimal height/width
// $iPositionX = null;
// $iPositionY = null;
// $iWidth = array_key_exists('preferred_width', $aDashletsInfo) ? $aDashletsInfo['preferred_width'] : 1;
// $iHeight = array_key_exists('preferred_height', $aDashletsInfo) ? $aDashletsInfo['preferred_height'] : 1;
// $oDashboardGrid->AddDashlet($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams), $sDashletId, $sDashletClass, $aDashletDenormalizedProperties, $iPositionX, $iPositionY, $iWidth, $iHeight);
$oDashboardColumn->AddUIBlock($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams));
}
}
@@ -163,7 +147,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
}
// TODO 3.3 We can probably do better with the new dashboard
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
if ($bEditMode) { // Add one row for extensibility
@@ -185,8 +168,8 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
*/
public function GetDashletCoordinates($iCellIdx)
{
$iColNumber = (int)$iCellIdx % $this->iNbCols;
$iRowNumber = (int)floor($iCellIdx / $this->iNbCols);
$iColNumber = (int) $iCellIdx % $this->iNbCols;
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
return [$iColNumber, $iRowNumber];
}
@@ -199,12 +182,11 @@ class DashboardLayoutOneCol extends DashboardLayoutMultiCol
parent::__construct();
$this->iNbCols = 1;
}
public static function GetInfo()
{
return [
'label' => 'One Column',
'icon' => 'images/layout_1col.png',
'label' => 'One Column',
'icon' => 'images/layout_1col.png',
'description' => '',
];
}
@@ -217,12 +199,11 @@ class DashboardLayoutTwoCols extends DashboardLayoutMultiCol
parent::__construct();
$this->iNbCols = 2;
}
public static function GetInfo()
{
return [
'label' => 'Two Columns',
'icon' => 'images/layout_2col.png',
'label' => 'Two Columns',
'icon' => 'images/layout_2col.png',
'description' => '',
];
}
@@ -235,12 +216,11 @@ class DashboardLayoutThreeCols extends DashboardLayoutMultiCol
parent::__construct();
$this->iNbCols = 3;
}
public static function GetInfo()
{
return [
'label' => 'Two Columns',
'icon' => 'images/layout_3col.png',
'label' => 'Two Columns',
'icon' => 'images/layout_3col.png',
'description' => '',
];
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
<class id="AbstractResource" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<comment>/* Resource access control abstraction. Can be inherited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
<abstract>true</abstract>
</properties>
<presentation/>
@@ -851,295 +851,9 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
</methods>
</class>
</classes>
<dashlets>
<dashlet id="DashletGroupByTable" _delta="define">
<label>UI:DashletGroupByTable:Label</label>
<icon>images/dashlets/icons8-transaction-list-48.png</icon>
<description>UI:DashletGroupByTable:Description</description>
<min_width>2</min_width>
<min_height>2</min_height>
<preferred_width>3</preferred_width>
<preferred_height>3</preferred_height>
<can_create_by_oql>true</can_create_by_oql>
<configuration/>
</dashlet>
<dashlet id="DashletGroupByBars" _delta="define">
<label>UI:DashletGroupByBars:Label</label>
<icon>images/dashlets/icons8-bar-chart-48.png</icon>
<description>UI:DashletGroupByBars:Description</description>
<min_width>2</min_width>
<min_height>2</min_height>
<preferred_width>3</preferred_width>
<preferred_height>3</preferred_height>
<can_create_by_oql>true</can_create_by_oql>
<configuration/>
</dashlet>
<dashlet id="DashletGroupByPie" _delta="define">
<label>UI:DashletGroupByPie:Label</label>
<icon>images/dashlets/icons8-pie-chart-48.png</icon>
<description>UI:DashletGroupByPie:Description</description>
<min_width>2</min_width>
<min_height>2</min_height>
<preferred_width>3</preferred_width>
<preferred_height>3</preferred_height>
<can_create_by_oql>true</can_create_by_oql>
<configuration/>
</dashlet>
<dashlet id="DashletBadge" _delta="define">
<label>UI:DashletBadge:Label</label>
<icon>images/dashlets/icons8-badge-48.png</icon>
<description>UI:DashletBadge:Description</description>
<min_width>2</min_width>
<min_height>1</min_height>
<preferred_width>2</preferred_width>
<preferred_height>1</preferred_height>
<configuration/>
</dashlet>
<dashlet id="DashletHeaderDynamic" _delta="define">
<label>UI:DashletHeaderDynamic:Label</label>
<icon>images/dashlets/icons8-header-altered-48.png</icon>
<description>UI:DashletHeaderDynamic:Description</description>
<min_width>2</min_width>
<min_height>1</min_height>
<preferred_width>4</preferred_width>
<preferred_height>3</preferred_height>
<configuration/>
</dashlet>
<dashlet id="DashletHeaderStatic" _delta="define">
<label>UI:DashletHeaderStatic:Label</label>
<icon>images/dashlets/icons8-header-48.png</icon>
<description>UI:DashletHeaderStatic:Description</description>
<min_width>4</min_width>
<min_height>1</min_height>
<preferred_width>4</preferred_width>
<preferred_height>1</preferred_height>
<configuration/>
</dashlet>
<dashlet id="DashletObjectList" _delta="define">
<label>UI:DashletObjectList:Label</label>
<icon>images/dashlets/icons8-list-48.png</icon>
<description>UI:DashletObjectList:Description</description>
<min_width>2</min_width>
<min_height>1</min_height>
<preferred_width>4</preferred_width>
<preferred_height>3</preferred_height>
<can_create_by_oql>true</can_create_by_oql>
<configuration/>
</dashlet>
<dashlet id="DashletPlainText" _delta="define">
<label>UI:DashletPlainText:Label</label>
<icon>images/dashlets/icons8-text-box-48.png</icon>
<description>UI:DashletPlainText:Description</description>
<min_width>2</min_width>
<min_height>1</min_height>
<preferred_width>2</preferred_width>
<preferred_height>1</preferred_height>
<configuration/>
</dashlet>
</dashlets>
<property_types _delta="define">
<property_type id="Dashboard" xsi:type="Combodo-AbstractPropertyType"/>
<property_type id="DashboardGrid" xsi:type="Combodo-PropertyType">
<extends>Dashboard</extends>
<definition xsi:type="Combodo-ValueType-PropertyTree">
<label>Dashboard</label>
<nodes>
<node id="title" xsi:type="Combodo-ValueType-String">
<label>UI:DashboardEdit:DashboardTitle</label>
</node>
<node id="refresh" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
<label>UI:DashboardEdit:AutoReload</label>
<values>
<value id="0">
<label>No auto-refresh</label>
</value>
<value id="30">
<label>Every 30 seconds</label>
</value>
<value id="60">
<label>Every 1 minute</label>
</value>
<value id="300">
<label>Every 5 minutes</label>
</value>
<value id="600">
<label>Every 10 minutes</label>
</value>
<value id="1800">
<label>Every 30 minutes</label>
</value>
<value id="3600">
<label>Every 1 hour</label>
</value>
</values>
</node>
<node id="pos_dashlets" xsi:type="Combodo-ValueType-Collection">
<label>Dashlet List</label>
<xml-format xsi:type="Combodo-XMLFormat-CollectionWithId">
<tag-name>pos_dashlet</tag-name>
</xml-format>
<prototype>
<node id="position_x" xsi:type="Combodo-ValueType-Integer">
<label>X</label>
</node>
<node id="position_y" xsi:type="Combodo-ValueType-Integer">
<label>Y</label>
</node>
<node id="width" xsi:type="Combodo-ValueType-Integer">
<label>W</label>
</node>
<node id="height" xsi:type="Combodo-ValueType-Integer">
<label>H</label>
</node>
<node id="dashlet" xsi:type="Combodo-ValueType-Polymorphic">
<label>Dashlet</label>
<allowed-types>
<allowed-type>Dashlet</allowed-type>
</allowed-types>
</node>
</prototype>
</node>
</nodes>
</definition>
</property_type>
<property_type id="Dashlet" xsi:type="Combodo-AbstractPropertyType"/>
<property_type id="DashletGroupByTable" xsi:type="Combodo-PropertyType">
<extends>Dashlet</extends>
<definition xsi:type="Combodo-ValueType-PropertyTree">
<label>UI:DashletGroupBy:Title</label>
<nodes>
<node id="title" xsi:type="Combodo-ValueType-Label">
<label>UI:DashletGroupBy:Prop-Title</label>
</node>
<node id="query" xsi:type="Combodo-ValueType-OQL">
<label>UI:DashletGroupBy:Prop-Query</label>
</node>
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
<label>UI:DashletGroupBy:Prop-GroupBy</label>
<class>{{query.selected_class}}</class>
</node>
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
<label>UI:DashletGroupBy:Prop-Style</label>
<values>
<value id="bars">
<label>UI:DashletGroupByBars:Label</label>
</value>
<value id="pie">
<label>UI:DashletGroupByPie:Label</label>
</value>
<value id="table">
<label>UI:DashletGroupByTable:Label</label>
</value>
</values>
</node>
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
<label>UI:DashletGroupBy:Prop-Function</label>
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
</node>
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
<class>{{query.selected_class}}</class>
<category>numeric</category>
</node>
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
<label>UI:DashletGroupBy:Prop-OrderField</label>
<values>
<value id="attribute">
<label>{{aggregation_attribute.label}}</label>
</value>
<value id="function">
<label>{{aggregation_function.label}}</label>
</value>
</values>
</node>
<node id="limit" xsi:type="Combodo-ValueType-Integer">
<label>UI:DashletGroupBy:Prop-Limit</label>
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
</node>
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
<values>
<value id="asc">
<label>UI:DashletGroupBy:Order:asc</label>
</value>
<value id="desc">
<label>UI:DashletGroupBy:Order:desc</label>
</value>
</values>
</node>
</nodes>
</definition>
</property_type>
<property_type id="DashletGroupByBars" xsi:type="Combodo-PropertyType">
<extends>Dashlet</extends>
<definition xsi:type="Combodo-ValueType-PropertyTree">
<label>UI:DashletGroupBy:Title</label>
<nodes>
<node id="title" xsi:type="Combodo-ValueType-Label">
<label>UI:DashletGroupBy:Prop-Title</label>
</node>
<node id="query" xsi:type="Combodo-ValueType-OQL">
<label>UI:DashletGroupBy:Prop-Query</label>
</node>
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
<label>UI:DashletGroupBy:Prop-GroupBy</label>
<class>{{query.selected_class}}</class>
</node>
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
<label>UI:DashletGroupBy:Prop-Style</label>
<values>
<value id="bars">
<label>UI:DashletGroupByBars:Label</label>
</value>
<value id="pie">
<label>UI:DashletGroupByPie:Label</label>
</value>
<value id="table">
<label>UI:DashletGroupByTable:Label</label>
</value>
</values>
</node>
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
<label>UI:DashletGroupBy:Prop-Function</label>
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
</node>
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
<class>{{query.selected_class}}</class>
<category>numeric</category>
</node>
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
<label>UI:DashletGroupBy:Prop-OrderField</label>
<values>
<value id="attribute">
<label>{{aggregation_attribute.label}}</label>
</value>
<value id="function">
<label>{{aggregation_function.label}}</label>
</value>
</values>
</node>
<node id="limit" xsi:type="Combodo-ValueType-Integer">
<label>UI:DashletGroupBy:Prop-Limit</label>
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
</node>
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
<values>
<value id="asc">
<label>UI:DashletGroupBy:Order:asc</label>
</value>
<value id="desc">
<label>UI:DashletGroupBy:Order:desc</label>
</value>
</values>
</node>
</nodes>
</definition>
</property_type>
<property_type id="DashletGroupByPie" xsi:type="Combodo-PropertyType">
<property_type id="DashletGroupBy" xsi:type="Combodo-PropertyType">
<extends>Dashlet</extends>
<definition xsi:type="Combodo-ValueType-PropertyTree">
<label>UI:DashletGroupBy:Title</label>

View File

@@ -6,7 +6,6 @@
*/
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
@@ -1280,14 +1279,13 @@ class DashboardMenuNode extends MenuNode
if ($oDashboard != null) {
WebResourcesHelper::EnableC3JSToWebPage($oPage);
// TODO 3.3 this works for dashboard menu, what about other places ?
$oPageLayout = PageContentFactory::MakeForDashboard();
$oPage->SetContentLayout($oPageLayout, $oPage);
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
$oPage->add('<div id="'.$sDivId.'" class="ibo-dashboard" data-role="ibo-dashboard">');
$aExtraParams['dashboard_div_id'] = $sDivId;
$aExtraParams['from_dashboard_page'] = true;
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
$oDashboard->Render($oPage, false, $aExtraParams);
$oPage->add('</div>');
$bEdit = utils::ReadParam('edit', false);
if ($bEdit) {

View File

@@ -1954,11 +1954,6 @@ class Config
*/
protected $m_sDefaultLanguage;
/**
* @var string Type of login process allowed: form|basic|url|external
*/
protected $m_sAllowedLoginTypes;
/**
* @var string Name of the PHP variable in which external authentication information is passed by the web server
*/
@@ -2032,7 +2027,6 @@ class Config
$this->m_iFastReloadInterval = DEFAULT_FAST_RELOAD_INTERVAL;
$this->m_bSecureConnectionRequired = DEFAULT_SECURE_CONNECTION_REQUIRED;
$this->m_sDefaultLanguage = 'EN US';
$this->m_sAllowedLoginTypes = DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = DEFAULT_EXT_AUTH_VARIABLE;
$this->m_aCharsets = [];
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
@@ -2179,7 +2173,6 @@ class Config
$this->m_aModuleSettings = isset($MyModuleSettings) ? $MyModuleSettings : [];
$this->m_sDefaultLanguage = isset($MySettings['default_language']) ? trim($MySettings['default_language']) : 'EN US';
$this->m_sAllowedLoginTypes = isset($MySettings['allowed_login_types']) ? trim($MySettings['allowed_login_types']) : DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = isset($MySettings['ext_auth_variable']) ? trim($MySettings['ext_auth_variable']) : DEFAULT_EXT_AUTH_VARIABLE;
$this->m_sEncryptionKey = isset($MySettings['encryption_key']) ? trim($MySettings['encryption_key']) : $this->m_sEncryptionKey;
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
@@ -2339,7 +2332,7 @@ class Config
public function GetAllowedLoginTypes()
{
return explode('|', $this->m_sAllowedLoginTypes);
return explode('|', $this->m_aSettings['allowed_login_types']['value']);
}
public function GetExternalAuthenticationVariable()
@@ -2417,7 +2410,6 @@ class Config
public function SetAllowedLoginTypes($aAllowedLoginTypes)
{
$this->m_sAllowedLoginTypes = implode('|', $aAllowedLoginTypes);
$this->Set('allowed_login_types', implode('|', $aAllowedLoginTypes));
}
@@ -2495,7 +2487,6 @@ class Config
$aSettings['fast_reload_interval'] = $this->m_iFastReloadInterval;
$aSettings['secure_connection_required'] = $this->m_bSecureConnectionRequired;
$aSettings['default_language'] = $this->m_sDefaultLanguage;
$aSettings['allowed_login_types'] = $this->m_sAllowedLoginTypes;
$aSettings['ext_auth_variable'] = $this->m_sExtAuthVariable;
$aSettings['encryption_key'] = $this->m_sEncryptionKey;
$aSettings['encryption_library'] = $this->m_sEncryptionLibrary;
@@ -2599,7 +2590,6 @@ class Config
// Old fashioned remaining values
$aOtherValues = [
'default_language' => $this->m_sDefaultLanguage,
'allowed_login_types' => $this->m_sAllowedLoginTypes,
'ext_auth_variable' => $this->m_sExtAuthVariable,
'encryption_key' => $this->m_sEncryptionKey,
'encryption_library' => $this->m_sEncryptionLibrary,

View File

@@ -1,18 +1,20 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\EventRegister\ApplicationEvents;
use Combodo\iTop\Core\Kpi\KpiLogData;
use Combodo\iTop\Service\Events\EventService;
use Combodo\iTop\Service\Events\iEventServiceSetup;
use Combodo\iTop\Service\Module\ModuleService;
/**
* Measures operations duration, memory usage, etc. (and some other KPIs)
*/
class ExecutionKPI
class ExecutionKPI implements iEventServiceSetup
{
protected static $m_bEnabled_Duration = false;
protected static $m_bEnabled_Memory = false;
@@ -23,15 +25,18 @@ class ExecutionKPI
protected static $m_aStats = []; // Recurrent operations
protected static $m_aExecData = []; // One shot operations
/**
* @var array[ExecutionKPI]
*/
protected static $m_aExecutionStack = []; // embedded execution stats
/** @var true */
private static bool $bMetamodelStarted = false;
private static ?float $fLastReportTime = null;
private static ?float $iLastReportMemory = null;
// For stats
protected $m_fStarted = null;
protected $m_fChildrenDuration = 0; // Count embedded
protected $m_iInitialMemory = null;
private static array $aBootstrapOperations = [];
public static function EnableDuration($iLevel)
{
if ($iLevel > 0) {
@@ -71,6 +76,7 @@ class ExecutionKPI
return true;
}
}
return false;
}
@@ -97,7 +103,7 @@ class ExecutionKPI
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
$sSlowQueries = '';
if (self::$m_fSlowQueries > 0) {
$sSlowQueries = ". Slow Queries: ".self::$m_fSlowQueries."s";
$sSlowQueries = '. Slow Queries: '.self::$m_fSlowQueries.'s';
}
$aExtensions = [];
@@ -127,7 +133,7 @@ class ExecutionKPI
$sRequest .= ' operation: '.$_POST['operation'];
}
$fStop = MyHelpers::getmicrotime();
$fStop = microtime(true);
if (($fStop - $fItopStarted) > self::$m_fSlowQueries) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
@@ -151,17 +157,17 @@ class ExecutionKPI
$sTableStyle = 'background-color: #ccc; margin: 10px;';
$sHtml = "<hr/>";
$sHtml = '<hr/>';
$sHtml .= "<div style=\"background-color: grey; padding: 10px;\">";
$sHtml .= "<h3><a name=\"".md5($sExecId)."\">KPIs</a> - $sRequest</h3>";
$oStarted = DateTime::createFromFormat('U.u', $fItopStarted);
$sHtml .= '<p>'.$oStarted->format('Y-m-d H:i:s.u').'</p>';
$sHtml .= "<p>log_kpi_user_id: ".UserRights::GetUserId()."</p>";
$sHtml .= "<div>";
$sHtml .= '<p>log_kpi_user_id: '.UserRights::GetUserId().'</p>';
$sHtml .= '<div>';
$sHtml .= "<table border=\"1\" style=\"$sTableStyle\">";
$sHtml .= "<thead>";
$sHtml .= " <th>Operation</th><th>Begin</th><th>End</th><th>Duration</th><th>Memory start</th><th>Memory end</th><th>Memory peak</th>";
$sHtml .= "</thead>";
$sHtml .= '<thead>';
$sHtml .= ' <th>Operation</th><th>Begin</th><th>End</th><th>Duration</th><th>Memory start</th><th>Memory end</th><th>Memory peak</th>';
$sHtml .= '</thead>';
foreach (self::$m_aExecData as $aOpStats) {
$sOperation = $aOpStats['op'];
$sBegin = round($aOpStats['time_begin'], 3);
@@ -180,12 +186,12 @@ class ExecutionKPI
}
}
$sHtml .= "<tr>";
$sHtml .= '<tr>';
$sHtml .= " <td>$sOperation</td><td>$sBegin</td><td>$sEnd</td><td>$sDuration</td><td>$sMemBegin</td><td>$sMemEnd</td><td>$sMemPeak</td>";
$sHtml .= "</tr>";
$sHtml .= '</tr>';
}
$sHtml .= "</table>";
$sHtml .= "</div>";
$sHtml .= '</table>';
$sHtml .= '</div>';
$aConsolidatedStats = [];
foreach (self::$m_aStats as $sOperation => $aOpStats) {
@@ -208,20 +214,20 @@ class ExecutionKPI
}
}
$aConsolidatedStats[$sOperation] = [
'count' => $iTotalOp,
'count' => $iTotalOp,
'duration' => $fTotalOp,
'min' => $fMinOp,
'max' => $fMaxOp,
'avg' => $fTotalOp / $iTotalOp,
'min' => $fMinOp,
'max' => $fMaxOp,
'avg' => $fTotalOp / $iTotalOp,
'max_args' => $sMaxOpArguments,
];
}
$sHtml .= "<div>";
$sHtml .= '<div>';
$sHtml .= "<table border=\"1\" style=\"$sTableStyle\">";
$sHtml .= "<thead>";
$sHtml .= " <th>Operation</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th><th>Avg</th>";
$sHtml .= "</thead>";
$sHtml .= '<thead>';
$sHtml .= ' <th>Operation</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th><th>Avg</th>';
$sHtml .= '</thead>';
foreach ($aConsolidatedStats as $sOperation => $aOpStats) {
$sOperation = '<a href="#'.md5($sExecId.$sOperation).'">'.$sOperation.'</a>';
$sCount = $aOpStats['count'];
@@ -230,14 +236,14 @@ class ExecutionKPI
$sMax = '<a href="#'.md5($sExecId.$aOpStats['max_args']).'">'.round($aOpStats['max'], 3).'</a>';
$sAvg = round($aOpStats['avg'], 3);
$sHtml .= "<tr>";
$sHtml .= '<tr>';
$sHtml .= " <td>$sOperation</td><td>$sCount</td><td>$sDuration</td><td>$sMin</td><td>$sMax</td><td>$sAvg</td>";
$sHtml .= "</tr>";
$sHtml .= '</tr>';
}
$sHtml .= "</table>";
$sHtml .= "</div>";
$sHtml .= '</table>';
$sHtml .= '</div>';
$sHtml .= "</div>";
$sHtml .= '</div>';
$sHtml .= "<p><a href=\"#end-".md5($sExecId)."\">Next page stats</a></p>";
@@ -287,18 +293,18 @@ class ExecutionKPI
$sOperationHtml = '<a name="'.md5($sExecId.$sOperation).'">'.$sOperation.'</a>';
$sHtml .= "<h4>$sOperationHtml</h4>";
$sHtml .= "<table border=\"1\" style=\"$sTableStyle\">";
$sHtml .= "<thead>";
$sHtml .= " <th>Operation details (+ blame caller if log_kpi_duration = 2)</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th>";
$sHtml .= "</thead>";
$sHtml .= '<thead>';
$sHtml .= ' <th>Operation details (+ blame caller if log_kpi_duration = 2)</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th>';
$sHtml .= '</thead>';
$bDisplayHeader = false;
}
$sHtml .= "<tr>";
$sHtml .= '<tr>';
$sHtml .= " <td>$sHtmlArguments</td><td>$iCountInter</td><td>$sTotalInter</td><td>$sMinInter</td><td>$sMaxInter</td>";
$sHtml .= "</tr>";
$sHtml .= '</tr>';
}
}
if (!$bDisplayHeader) {
$sHtml .= "</table>";
$sHtml .= '</table>';
$sHtml .= "<p><a href=\"#".md5($sExecId)."\">Back to page stats</a></p>";
}
self::Report($sHtml);
@@ -333,39 +339,50 @@ class ExecutionKPI
$aNewEntry = null;
$fStarted = $this->m_fStarted;
$fStopped = $this->m_fStarted;
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$aNewEntry = [
'op' => $sOperationDesc,
'time_begin' => $this->m_fStarted - $fItopStarted,
'time_end' => $fStopped - $fItopStarted,
];
// Reset for the next operation (if the object is recycled)
$this->m_fStarted = $fStopped;
if (is_null(static::$fLastReportTime)) {
static::$fLastReportTime = $fItopStarted;
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (is_null(static::$iLastReportMemory)) {
global $iItopInitialMemory;
static::$iLastReportMemory = $iItopInitialMemory;
}
$fStarted = static::$fLastReportTime;
$fStopped = microtime(true);
if (self::$m_bEnabled_Duration) {
$aNewEntry = [
'op' => $sOperationDesc,
'time_begin' => $fStarted - $fItopStarted,
'time_end' => $fStopped - $fItopStarted,
];
}
static::$fLastReportTime = $fStopped;
$iInitialMemory = static::$iLastReportMemory;
$iCurrentMemory = $iInitialMemory;
$iPeakMemory = $iInitialMemory;
if (self::$m_bEnabled_Memory) {
$iCurrentMemory = self::memory_get_usage();
if (is_null($aNewEntry)) {
$aNewEntry = ['op' => $sOperationDesc];
}
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
$aNewEntry['mem_begin'] = $iInitialMemory;
$aNewEntry['mem_end'] = $iCurrentMemory;
$iPeakMemory = self::memory_get_peak_usage();
$aNewEntry['mem_peak'] = $iPeakMemory;
// Reset for the next operation (if the object is recycled)
$this->m_iInitialMemory = $iCurrentMemory;
static::$iLastReportMemory = $iCurrentMemory;
}
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$aCallstack = ['callstack' => $this->GetCallStack()];
if (static::$bMetamodelStarted) {
foreach (static::$aBootstrapOperations as $oLog) {
$this->LogOperation($oLog);
}
static::$aBootstrapOperations = [];
// Invoke extensions to log the KPI operation
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_REPORT,
@@ -376,9 +393,24 @@ class ExecutionKPI
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory
$iPeakMemory,
$aCallstack
);
$oExtensionInstance->LogOperation($oKPILogData);
$this->LogOperation($oKPILogData);
} else {
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_REPORT,
'Step',
$sOperationDesc,
$fStarted,
$fStopped,
'',
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack
);
static::$aBootstrapOperations[] = $oKPILogData;
}
}
@@ -388,13 +420,21 @@ class ExecutionKPI
$this->ResetCounters();
}
private function LogOperation(KpiLogData $oKPILogData): void
{
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oExtensionInstance->LogOperation($oKPILogData);
}
}
/**
* Compute statistics for a call to an extension
* Note: not working in dev mode (with links to env-production)
*
* @param object|string $object object called
* @param string $sMethod method called on the object
* @param string $sMessage additional message
* @param string $sMethod method called on the object
* @param string $sMessage additional message
*
* @return bool true if an extension was found for this object::method
* @throws \ReflectionException
@@ -423,21 +463,23 @@ class ExecutionKPI
$fDuration = 0;
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$fStopped = microtime(true);
$fDuration = $fStopped - $this->m_fStarted;
$aCallstack = [];
if (self::$m_bGenerateLegacyReport) {
if (self::$m_bBlameCaller) {
$aCallstack = MyHelpers::get_callstack(1);
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
'callers' => $aCallstack,
'time' => $fDuration,
'callers' => $aCallstack,
];
} else {
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
'time' => $fDuration,
];
}
} else {
$aCallstack = ['callstack' => $this->GetCallStack()];
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
@@ -448,33 +490,45 @@ class ExecutionKPI
$iPeakMemory = self::memory_get_peak_usage();
}
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
//$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$sExtension = '';
if (static::$bMetamodelStarted) {
foreach (static::$aBootstrapOperations as $oLog) {
$this->LogOperation($oLog);
}
static::$aBootstrapOperations = [];
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,
$sArguments,
$this->m_fStarted,
$fStopped,
$sExtension,
'',
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack
);
$oExtensionInstance->LogOperation($oKPILogData);
$this->LogOperation($oKPILogData);
} else {
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,
$sArguments,
$this->m_fStarted,
$fStopped,
'',
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack
);
static::$aBootstrapOperations[] = $oKPILogData;
}
}
}
protected function ResetCounters()
{
if (self::$m_bEnabled_Duration) {
$this->m_fStarted = microtime(true);
}
$this->m_fStarted = microtime(true);
if (self::$m_bEnabled_Memory) {
$this->m_iInitialMemory = self::memory_get_usage();
@@ -503,7 +557,33 @@ class ExecutionKPI
if (function_exists('memory_get_peak_usage')) {
return memory_get_peak_usage($bRealUsage);
}
// PHP > 5.2.1 - this verb depends on a compilation option
return 0;
}
/*
* ModuleHandlerApiInterface methods
*/
public static function OnMetaModelStarted()
{
static::$bMetamodelStarted = true;
}
public function RegisterEventsAndListeners()
{
EventService::RegisterListener(ApplicationEvents::APPLICATION_EVENT_METAMODEL_STARTED, [$this, 'OnMetaModelStarted']);
}
private function GetCallStack(): string
{
$aCallStack = MyHelpers::get_callstack(2);
$sCallStack = "Call stack:\n";
foreach ($aCallStack as $index => $aLine) {
$sCallStack .= "#$index ".$aLine['File'].'('.$aLine['Line'].'): '.$aLine['Function']."\n";
}
return $sCallStack;
}
}

View File

@@ -89,17 +89,9 @@ abstract class ModelReflection
* @param string $defaultValue
*
* @return \RunTimeIconSelectionField
* @deprecated since 3.3.0 replaced by GetAvailableIcons
*/
abstract public function GetIconSelectionField($sCode, $sLabel = '', $defaultValue = '');
/**
* Find available icons for the current context
*
* @return array of ['value', 'label', 'icon'] where 'value' is the relative path on disk, 'label' the name to display and 'icon' is the URL to get the image
*/
abstract public function GetAvailableIcons(): array;
abstract public function GetRootClass($sClass);
abstract public function EnumChildClasses($sClass, $iOption = ENUM_CHILD_CLASSES_EXCLUDETOP);
}
@@ -117,8 +109,6 @@ abstract class QueryReflection
class ModelReflectionRuntime extends ModelReflection
{
private static array $aAllIcons = [];
public function __construct()
{
}
@@ -265,52 +255,6 @@ class ModelReflectionRuntime extends ModelReflection
return new RunTimeIconSelectionField($sCode, $sLabel, $defaultValue);
}
public function GetAvailableIcons(): array
{
$aFolderList = [
APPROOT.'env-'.utils::GetCurrentEnvironment() => utils::GetAbsoluteUrlModulesRoot(),
APPROOT.'images/icons' => utils::GetAbsoluteUrlAppRoot().'images/icons',
];
if (count(self::$aAllIcons) == 0) {
foreach ($aFolderList as $sFolderPath => $sUrlPrefix) {
$aIcons = self::FindIconsOnDisk($sFolderPath);
ksort($aIcons);
foreach ($aIcons as $sFilePath) {
self::$aAllIcons[] = ['value' => $sFilePath, 'label' => basename($sFilePath), 'icon' => $sUrlPrefix.$sFilePath];
}
}
}
return self::$aAllIcons;
}
private static function FindIconsOnDisk(string $sBaseDir, string $sDir = '', array &$aFilesSpecs = []): array
{
$aResult = [];
// Populate automatically the list of icon files
if ($hDir = @opendir($sBaseDir.'/'.$sDir)) {
while (($sFile = readdir($hDir)) !== false) {
$aMatches = [];
if (($sFile != '.') && ($sFile != '..') && ($sFile != 'lifecycle') && is_dir($sBaseDir.'/'.$sDir.'/'.$sFile)) {
$sDirSubPath = ($sDir == '') ? $sFile : $sDir.'/'.$sFile;
$aResult = array_merge($aResult, self::FindIconsOnDisk($sBaseDir, $sDirSubPath, $aFilesSpecs));
}
$sSize = filesize($sBaseDir.'/'.$sDir.'/'.$sFile);
if (isset($aFilesSpecs[$sFile]) && $aFilesSpecs[$sFile] == $sSize) {
continue;
}
if (preg_match('/\.(png|jpg|jpeg|gif|svg)$/i', $sFile, $aMatches)) { // png, jp(e)g, gif and svg are considered valid
$aResult[$sFile.'_'.$sDir] = $sDir.'/'.$sFile;
$aFilesSpecs[$sFile] = $sSize;
}
}
closedir($hDir);
}
return $aResult;
}
public function GetRootClass($sClass)
{
return MetaModel::GetRootClass($sClass);

View File

@@ -75,26 +75,3 @@ collection-entry-element {
resize: vertical;
}
.ibo-form-compact{
.ibo-field{
display: flex;
flex-direction: column;
gap: 4px;
label{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
max-width: unset;
padding-right: 0;
}
}
}

View File

@@ -19,10 +19,7 @@ $ibo-dashlet-blocker--height: 100% !default;
.ibo-dashlet {
position: relative;
width: calc(#{$ibo-dashlet--width} - #{$ibo-dashlet--elements-spacing-x});
//margin: calc(#{$ibo-dashlet--elements-spacing-y} / 2) calc(#{$ibo-dashlet--elements-spacing-x} / 2);
height: 100% !important;
width: 100% !important;
margin: calc(#{$ibo-dashlet--elements-spacing-y} / 2) calc(#{$ibo-dashlet--elements-spacing-x} / 2);
&.dashlet-selected {
position: relative;
@@ -41,21 +38,4 @@ $ibo-dashlet-blocker--height: 100% !default;
width: $ibo-dashlet-blocker--width;
height: $ibo-dashlet-blocker--height;
cursor: not-allowed;
}
.ibo-dashlet--actions {
position: absolute;
z-index: 1000;
top: 0px;
right: 0px;
display: none;
padding: 4px;
border-radius: 4px;
background-color: $ibo-color-white-100;
@extend %ibo-elevation-100;
}
ibo-dashlet[data-edit-mode="edit"] {
z-index: 3;
}

View File

@@ -54,31 +54,3 @@ $ibo-input-select-icon--menu--icon--margin-right: 10px !default;
}
}
}
.ts-control > .ibo-input-select-icon--menu--item{
display: flex;
column-gap: 5px;
align-items: center;
padding: 5px 0;
> img{
width: 20px;
}
&:hover{
background: transparent;
}
}
.ts-dropdown > .ts-dropdown-content > .ibo-input-select-icon--menu--item{
display: flex;
column-gap: 5px;
> img{
width: 32px;
}
}

View File

@@ -15,4 +15,3 @@
@import "wizard-container/wizard-container";
@import "object/all";
@import "activity-panel/all";
@import "dashlet-panel/all";

View File

@@ -175,73 +175,3 @@ input:checked + .ibo-dashboard--slider:before {
input:checked + .ibo-dashboard--slider:after {
content: $ibo-dashboard--slider--before--content;
}
// TODO 3.3 Cleanup variables
// TODO 3.3 Move to vendor what's from gridstack
.grid-stack {
display: block;
}
.ibo-dashboard[data-edit-mode="edit"] .grid-stack{
background-size: calc(100% / 12) var(--gs-cell-height);
background-color: $ibo-color-white-100;
background-image: linear-gradient(to right, $ibo-color-white-200 8px, transparent 8px), linear-gradient(to bottom, $ibo-color-white-200 8px, transparent 8px);
--gs-item-margin-top: 8px;
--gs-item-margin-bottom: 0;
--gs-item-margin-right: 0;
--gs-item-margin-left: 8px;
}
ibo-dashboard[data-edit-mode="view"] {
.ibo-dashboard--form {
display: none;
}
}
.ibo-dashboard--form {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 55px;
background-color: $ibo-color-blue-200;
margin: -16px -36px 24px -36px;
padding: 0 36px;
}
.ibo-dashboard--form--inputs {
display: flex;
flex-direction: row;
align-items: center;
gap: 12px;
@extend %common-font-ral-med-250;
}
.ibo-dashboard[data-edit-mode="edit"] ibo-dashlet:not([data-edit-mode="edit"]):hover .ibo-dashlet--actions {
display: block;
}
.ibo-dashboard[data-edit-mode="error"] .grid-stack{
background-image: url($approot-relative + '/images/alpha-fatal-error.gif');
}
// Our edit mode dashboard already has its own header, so we hide the standard one
#ibo-page-header:has(+ ibo-dashboard[data-edit-mode="edit"]) {
display: none;
}
.ibo-dashboard[data-edit-mode="edit"] .ibo-dashboard--grid:has(ibo-dashboard-grid-slot > ibo-dashlet[data-edit-mode="edit"]) .ibo-dashboard--grid--backdrop {
position: absolute;
height: calc(100% + 24px);
// 36px is $ibo-page-container--elements-padding-x, handle variable resolution
width: calc(100% + 36px + 36px);
margin: -24px -#{36px} 0 -#{36px};
background-color: $ibo-color-grey-400;
z-index: 2;
opacity: 60%;
}

View File

@@ -1,2 +0,0 @@
@import "dashlet-entry";
@import "dashlet-panel";

View File

@@ -1,51 +0,0 @@
// TODO 3.3 Cleanup variables
.ibo-dashlet-entry {
display: flex;
flex-direction: row;
gap: 10px;
border: 1px solid $ibo-color-grey-300;
border-radius: 5px;
padding: 12px;
background-color: $ibo-color-grey-100;
cursor: pointer;
text-align: left;
&:hover {
background-color: $ibo-color-grey-200;
border-color: $ibo-color-grey-400;
}
&:active {
background-color: $ibo-color-grey-50;
border-color: $ibo-color-grey-500;
}
}
.ibo-dashlet-entry--icon {
flex-shrink: 0;
height: 36px;
width: 36px;
}
.ibo-dashlet-entry--content {
display: flex;
flex-direction: column;
justify-content: center;
overflow-x: hidden;
gap: 4px;
}
.ibo-dashlet-entry--title {
font-size: 14px;
font-weight: 600;
color: $ibo-color-grey-900;
}
.ibo-dashlet-entry--description {
font-size: 12px;
color: $ibo-color-grey-700;
}

View File

@@ -1,66 +0,0 @@
// TODO 3.3 Cleanup variables
.ibo-dashlet-panel {
height: 100%;
display: flex;
flex-direction: column;
width: 326px;
background-color: $ibo-color-white-100;
}
.ibo-dashlet-panel--title {
display: flex;
flex-direction: column;
justify-content: center;
height: 55px;
background-color: $ibo-color-white-200;
padding: 0 16px;
flex-grow: 0;
@extend %common-font-ral-med-300;
}
.ibo-dashlet-panel--entries, .ibo-dashlet-panel--form-container {
flex-grow: 1;
display: flex;
flex-direction: column;
overflow: auto;
padding: 16px;
gap: 12px;
&.ibo-is-hidden {
display: none;
}
}
.ibo-center-container:has(ibo-dashboard[data-edit-mode="view"]) .ibo-dashlet-panel{
display: none;
}
.ibo-dashlet-panel--form-container turbo-frame {
height: 100%;
}
.ibo-dashlet-panel--form-container .ibo-form {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
> .form {
overflow: auto;
margin-bottom: 16px;
}
}
.ibo-dashlet-panel--form-container--buttons {
display: flex;
flex-direction: row !important;
justify-content: end;
align-items: center;
margin: 0 -16px -16px -16px;
padding: 0 16px;
min-height: 60px;
background-color: $ibo-color-grey-50;
border-top: solid 1px $ibo-color-grey-400;
}

View File

@@ -5,9 +5,11 @@
$ibo-multi-column--margin-x: -$ibo-spacing-500 !default; /* This is to compensate columns padding and make the whole multicolumn align with the parent borders (cf. Bootstrap rows / cols) */
$ibo-multi-column--margin-y: $ibo-spacing-0 !default;
$ibo-multi-column--row-gap: $ibo-spacing-800 !default;
.ibo-multi-column {
display: flex;
flex-wrap: wrap;
margin: $ibo-multi-column--margin-y $ibo-multi-column--margin-x;
row-gap: $ibo-multi-column--row-gap;
}

View File

@@ -1,42 +1,205 @@
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<Brand alias="Brand" id="1">
<name>Acer</name>
</Brand>
<Brand alias="Brand" id="2">
<name>Apple</name>
</Brand>
<Brand alias="Brand" id="3">
<name>Asus</name>
</Brand>
<Brand alias="Brand" id="4">
<name>Cisco</name>
</Brand>
<Brand alias="Brand" id="5">
<name>Dell</name>
</Brand>
<Brand alias="Brand" id="6">
<name>HP Inc</name>
</Brand>
<Brand alias="Brand" id="7">
<name>HPE</name>
</Brand>
<Brand alias="Brand" id="8">
<name>IBM</name>
</Brand>
<Brand alias="Brand" id="9">
<name>Lenovo</name>
</Brand>
<Brand alias="Brand" id="10">
<name>Razer</name>
</Brand>
<Brand alias="Brand" id="11">
<name>Samsung</name>
</Brand>
<Brand alias="Brand" id="12">
<name>Sony</name>
</Brand>
<Brand alias="Brand" id="13">
<name>Toshiba</name>
</Brand>
<Brand alias="Brand" id="1">
<name>Acer</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icon-acer.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmc6c3ZnIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiIHhtbG5zOnN2Zz0iaH
R0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgaWQ9ImFjZXIiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iODMiIGhlaWdodD0iODMiIHZpZXdCb3g9IjAgMCA4MyA4MyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgc29kaXBvZGk6ZG9jbmFtZT0iaWNvbi1hY2VyLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS40LjMgKDBkMTVmNzUwNDIsIDIwMjUtMTItMjUpIj48c3ZnOmRlZnMgaWQ9ImRlZnMxIi8+PHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2
aWV3MSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9yZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgc2hvd2d1aWRlcz0idHJ1ZSIgaW5rc2NhcGU6em9vbT0iMTAuNDgzMDcxIiBpbmtzY2FwZTpjeD0iNzUuNzg4ODYiIGlua3NjYXBlOmN5PSIzNS
42NzY1NjgiIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMjU2MCIgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTM2MCIgaW5rc2NhcGU6d2luZG93LXg9IjAiIGlua3NjYXBlOndpbmRvdy15PSIwIiBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJhY2VyIj48c29kaXBvZGk6Z3VpZGUgcG9zaXRpb249IjQwLjMwNzkxOSw0MS4yMjAyMTQiIG9yaWVudGF0aW9uPSIwLC0xIiBpZD0iZ3VpZGUxIiBpbmtzY2FwZTpsb2NrZWQ9
ImZhbHNlIi8+PC9zb2RpcG9kaTpuYW1lZHZpZXc+Cjxzdmc6cGF0aCBpZD0iYWNlci1sb2dvIiBzdHlsZT0iZmlsbDojODBjMzQzIiBkPSJtIDgyLjg1LDMyLjc2MDg5MyBjIC0wLjI5LC0wLjQyIC0wLjYyLC0wLjcgLTIuMDQsLTAuODEgLTAuMzcsLTAuMDMgLTEuNiwtMC4wNyAtMy42NiwtMC4wNyAtNS40MiwwIC05LjEsMS42NSAtMTAuOTgsNC45MSAwLjUyLC0zLjI4IC0yLjY3LC00LjkyIC05LjU1LC00LjkyIC04LjA5LDAgLTEzLjE0LDMuMjcgLTE1LjE1LDkuOD
EgLTAuNzQsMS45MSAtMC44Miw0LjAyIC0wLjIzLDUuOTggbCAtMS45MSwwLjEzIGMgLTEuNDksMC4xMSAtMy40NiwwLjIyIC00LjY2LDAuMjIgLTIuOTYsMCAtNC44LC0wLjUgLTUuNTEsLTEuNSAtMC42NCwtMC45IC0wLjU3LC0yLjU2IDAuMTcsLTQuOTggMS4yMywtNC4wMiA0LjI5LC01LjgyIDkuMTgsLTUuODIgMi41MywwIDUsMC4yNyA1LDAuMjcgMC4zLC0wLjA1IDAuNTEsLTAuMzMgMC40NiwtMC42NCAwLC0wLjAxIDAsLTAuMDIgLTAuMDEsLTAuMDMgbCAtMC4w
NSwtMC4zOCAtMC4xNywtMS4zNSBjIC0wLjExLC0wLjg5IC0wLjc3LC0xLjQxIC0xLjk3LC0xLjU3IC0xLjEsLTAuMDcgLTEuOTEsLTAuMTMgLTMuMTIsLTAuMTMgaCAtMC4wNyBjIC02LjM5LDAuMDEgLTEwLjg0LDIuMTIgLTEzLjM2LDYuMzIgMC45MiwtNC4yMSAtMi4wNCwtNi4zMiAtOC44NywtNi4zMiAtMi43MywtMC4wNSAtNS40NiwwLjA2IC04LjE4LDAuMzMgLTEuMDMsLTAuMDMgLTEuOTYsMC42MSAtMi4zMywxLjU3IGwgLTAuNTQsMS43MyBjIC0wLjEsMC4zMi
AwLjA1LDAuNDggMC40NiwwLjQ4IGggMC4wMSBjIDAuMywtMC4wNCAxLjQ2LC0wLjE1IDMuNDQsLTAuMzEgMi42MiwtMC4yMSA0LjU1LC0wLjMyIDUuODMsLTAuMzIgMy43NywwIDUuMzUsMC45NSA0Ljc2LDIuODQgLTAuMTEsMC40IC0wLjQ0LDAuNzEgLTAuODUsMC43OCAtMy41NiwwLjU5IC02LjM5LDEuMDIgLTguNDgsMS4yOCAtNS44OSwwLjc1IC05LjI5LDIuNTkgLTEwLjIsNS41MiAtMS4yNSw0LjAzIDEuODksNi4wNCA5LjQ0LDYuMDQgMy4xNywwLjA0IDYuMzQs
LTAuMTggOS40OCwtMC42NSAxLjQ3LC0wLjI1IDIuMjIsLTAuNjMgMi41MSwtMS41OCBsIDEuNDEsLTQuNDkgYyAtMC4xNSw0LjQ5IDIuOTksNi43NSA5LjQxLDYuNzUgMi4yMywwLjA0IDQuNDUsLTAuMDYgNi42NiwtMC4zMSAxLjMyLC0wLjIzIDEuOTUsLTAuNTIgMi4yNCwtMS41MSBsIDAuMjgsLTEuNDEgYyAxLjM3LDIuMTQgNC4zNywzLjIxIDkuMDEsMy4yMSA0Ljg5LDAgNy43NCwtMC4xNCA4LjU1LC0wLjQxIDAuNTcsLTAuMTIgMS4wNCwtMC41MiAxLjI1LC0xLj
A2IDAuMDMsLTAuMDkgMC4wNSwtMC4xOSAwLjA2LC0wLjI4IGwgMC41OSwtMS45MSBjIDAuMSwtMC4zMyAtMC4wNSwtMC40OSAtMC40NSwtMC40OCBsIC0zLjEzLDAuMTUgYyAtMi4wOSwwLjEyIC0zLjcyLDAuMTggLTQuOSwwLjE3IC0xLjU0LDAuMDggLTMuMDgsLTAuMDcgLTQuNTgsLTAuNDYgLTEuMiwtMC40MSAtMS45NCwtMS42MSAtMS43NywtMi44NiBsIDkuOTEsLTEuMjcgYyA0LjQ0LC0wLjU3IDcuNDIsLTEuOTQgOC45MiwtNC4xMiBsIC0zLjM3LDExLjczIGMg
LTAuMDcsMC4xOCAtMC4wNCwwLjM4IDAuMDcsMC41MyAwLjE4LDAuMTcgMC40MSwwLjI1IDAuNjUsMC4yMiBoIDQuMSBjIDAuNDcsMC4wNyAwLjkzLC0wLjIyIDEuMDYsLTAuNjggbCAzLjYyLC0xMi42NyBjIDAuNDgsLTEuNjcgMiwtMi40OCA0LjY3LC0yLjQ4IDIuNDEsMCA0LjIyLDAuMDIgNS4zOCwwLjA3IDAuMDMsMCAwLjA2LDAgMC4wOSwwIDAuMzksMCAwLjc0LC0wLjI2IDAuODQsLTAuNjMgbCAwLjYzLC0xLjc0IGMgMC4xNSwtMC4zIDAuMTIsLTAuNjMgLTAuMD
UsLTAuODkgbSAtNjYuMTIsMTUuMjQgYyAtMS44MywwLjIzIC0zLjY4LDAuMzMgLTUuNTIsMC4zIC00LjE3LDAgLTUuOTksLTAuODQgLTUuNDYsLTIuNTMgMC4zOCwtMS4yMSAxLjQ3LC0xLjk0IDMuMjgsLTIuMTkgbCA5LjQ4LC0xLjI4IHogbSA0My44MywtMTAuMjcgYyAtMC40LDEuMyAtMi4yNSwyLjE5IC01LjU2LDIuNjcgbCAtNy45LDEuMTMgMC4yLC0wLjY1IGMgMC4zOSwtMS43NCAxLjM3LC0zLjI4IDIuNzksLTQuMzcgMS4yLC0wLjc3IDMuMTUsLTEuMTYgNS44NiwtMS4xNiAzLjU2LDAgNS4xLDAuOCA0LjYxLDIuMzgiLz4KPC9zdmc6c3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Acer</friendlyname>
</Brand>
<Brand alias="Brand" id="2">
<name>Apple</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-mac-os.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMwODgzZDkiIGQ9Ik0zNi4yMzIsMjMuOTg1YzAtNS44NjUsNC43NjYtOC41MSw0Ljk2Ni04LjYzNmMtMi41OTYtMy45OTMtNi43OS00LjQ2Ny
04LjM2Mi00LjQ2OCBjLTMuNjQzLDAtNi44NjMsMi4wMjItOC41ODUsMi4wMjJjLTEuNzk3LDAtNC40MTgtMi4xMjEtNy4zNjMtMi4wMjJjLTMuODQzLDAuMDc1LTcuMzYzLDIuMzQ2LTkuMzM0LDUuNjkxIGMtMS4zOTcsMi4zOTYtMS45NDcsNS4yMTctMS44OTYsOC4wODdjMC4wMDIsMC4xMTMsMC4wMTcsMC4yMjgsMC4wMiwwLjM0MUgzNi4zMkMzNi4yNzksMjQuNjcxLDM2LjI0MywyNC4zMzcsMzYuMjMyLDIzLjk4NXoiLz48cGF0aCBmaWxsPSIjMDg4M2Q5IiBkPSJN
MzAuNTY1LDcuMDYzQzMyLjI2MSw1LjE5MSwzMy4yMSwyLjYyMSwzMy4wNiwwYy0yLjM0NiwwLTUuMDY2LDEuMzcyLTYuNzg4LDMuMzk0IGMtMS4zNDgsMS42NzItMi43OTUsNC4yOTMtMi4yNzEsNi45MTNDMjYuNDIyLDEwLjYwNywyOS4wNDMsOS4wODUsMzAuNTY1LDcuMDYzeiIvPjxwYXRoIGZpbGw9IiMwMzcwYzgiIGQ9Ik0xNy41MTEsNDVjMi43NzEsMCwzLjc5NC0xLjg0OCw3LjQxMy0xLjg0OGMzLjM3LDAsNC40MTgsMS44NDgsNy4zMzgsMS44NDggYzMuMDcsMCw1LjA5Mi0yLjc5NSw2LjkxMy01LjU2N2MyLjI5NS0zLjIxOCwzLjA3LTYuMjg4LDMuMTY5LTYuNDE0Yy0wLjA5NCwwLTUuMjg3LTIuMTEyLTYuMDI2LTguMDE5SDUuNjc4IGMwLjE1Nyw1LjMxMSwyLjIyOCwxMC43OSw0LjY3MSwxNC4zMDlDMTIuMjcsNDIuMDU1LDE0LjQ0MSw0NSwxNy41MTEsNDV6Ii8+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Apple</friendlyname>
</Brand>
<Brand alias="Brand" id="3">
<name>Asus</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-asus.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dHA6Ly93
d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwLDAsMjU2LDI1NiIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCIgZmlsbC1ydWxlPSJub256ZXJvIiB2ZXJzaW9uPSIxLjEiIGlkPSJzdmcxMyIgc29kaXBvZGk6ZG9jbmFtZT0iaWNvbnM4LWFzdXMgKDEpLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS40LjMgKDBkMTVmNzUwNDIsIDIwMjUtMTItMjUpIj48c29kaXBvZGk6bmFtZWR2aWV3IGlkPS
JuYW1lZHZpZXcxMyIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9yZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgaW5rc2NhcGU6em9vbT0iMTcuMTg3NSIgaW5rc2NhcGU6Y3g9IjMxLjk3MDkwOSIgaW5rc2NhcGU6Y3k9IjMyIiBpbmtzY2FwZTp3
aW5kb3ctd2lkdGg9IjI1NjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNjAiIGlua3NjYXBlOndpbmRvdy14PSIwIiBpbmtzY2FwZTp3aW5kb3cteT0iMCIgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0iZzEzIi8+PGRlZnMgaWQ9ImRlZnMxMCI+PHJhZGlhbEdyYWRpZW50IGN4PSIzNC42MjUiIGN5PSIzMS44NzUiIHI9IjIzLjIwNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJjb2xvci0xIj
48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmNGU5YzMiIGlkPSJzdG9wMSIvPjxzdG9wIG9mZnNldD0iMC4yMTkiIHN0b3AtY29sb3I9IiNmOGVlY2QiIGlkPSJzdG9wMiIvPjxzdG9wIG9mZnNldD0iMC42NDQiIHN0b3AtY29sb3I9IiNmZGY0ZGMiIGlkPSJzdG9wMyIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZjZlMSIgaWQ9InN0b3A0Ii8+PC9yYWRpYWxHcmFkaWVudD48bGluZWFyR3JhZGllbnQgeDE9IjAuMzY1IiB5MT0iMzIuNSIgeDI9
IjY0IiB5Mj0iMzIuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJjb2xvci0yIj48c3RvcCBvZmZzZXQ9IjAuMDUzIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBpZD0ic3RvcDUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAwMDAiIGlkPSJzdG9wNiIvPjwvbGluZWFyR3JhZGllbnQ+PHJhZGlhbEdyYWRpZW50IGN4PSIzNC42MjUiIGN5PSIzMS44NzUiIHI9IjIzLjIwNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPS
Jjb2xvci0zIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmNGU5YzMiIGlkPSJzdG9wNyIvPjxzdG9wIG9mZnNldD0iMC4yMTkiIHN0b3AtY29sb3I9IiNmOGVlY2QiIGlkPSJzdG9wOCIvPjxzdG9wIG9mZnNldD0iMC42NDQiIHN0b3AtY29sb3I9IiNmZGY0ZGMiIGlkPSJzdG9wOSIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZjZlMSIgaWQ9InN0b3AxMCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVs
ZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIGZvbnQtZmFtaWx5PSJub25lIiBmb250LXdlaWdodD0ibm9uZSIgZm9udC1zaXplPSJub25lIiB0ZXh0LWFuY2hvcj0ibm9uZSIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiIGlkPSJnMT
MiPjxnIHRyYW5zZm9ybT0ic2NhbGUoNCw0KSIgaWQ9ImcxMiI+PHBhdGggZD0iTTYuMTU2LDI5LjI0M2wtNS43MjMsOS45MTljLTAuMTkyLDAuMzMzIDAuMDQ4LDAuNzUgMC40MzMsMC43NWgyLjc2NGMwLjM1NiwwIDAuNjg2LC0wLjE5IDAuODY1LC0wLjQ5OGw1LjYyOSwtOS43MDF6TTYuMjk5LDI5LjAwNWMwLDAgMC44MTUsLTEuNDg2IDEuNjI1LC0yLjkyYzAuMzU0LC0wLjYyOCAxLjAxOSwtMS4wMTQgMS43NCwtMS4wMTRjMS40MDgsMC4wMDEgMy43NTcsMC4wMDMg
NS4wODYsMC4wMDRjMC41NTIsMCAwLjk5NSwwLjQ0OCAwLjk5NSwxLjAwMXYyLjYxYzAsMCAwLjMyMywtMS4zODYgMC44OTEsLTIuMDQzYzAuNTM0LC0wLjYxOSAxLjI0NiwtMS40NzggMi44NzIsLTEuNTkyaDEwLjk2M2MwLjU1MiwwIDEsMC40NDggMSwxdjEuOTU1YzAsMC41NTIgLTAuNDQ4LDEgLTEsMXpNNjQsMjguMDA4di0xLjk1OGMwLC0wLjU1MiAtMC40NDgsLTEgLTEsLTFoLTExLjhjLTEuNjIyLDAuMTE0IC0yLjMzNywwLjk3MiAtMi44NzIsMS41OTJjLTAuNT
Y5LDAuNjU3IC0wLjg5LDIuMDQzIC0wLjg5LDIuMDQzdjAuMzE4bDE1LjU2MiwwLjAwNWMwLjU1MiwwIDEsLTAuNDQ4IDEsLTF6TTMzLjA5NSwyNS4wN2gxLjU3OGMwLjU1MiwwIDEsMC40NDggMSwxdjIuOTM1aC0zLjU3OHYtMi45MzVjMCwtMC41NTIgMC40NDgsLTEgMSwtMXpNNDQuODM5LDI1LjA3aDEuNTc0YzAuNTUyLDAgMSwwLjQ0OCAxLDF2Mi45MzVoLTMuNTc0di0yLjkzNWMwLC0wLjU1MiAwLjQ0NywtMSAxLC0xek00Ny40MTMsMzAuNDI1bC0zLjUxNCwtMC4y
MzN2NC41NjZjMCwwIC0wLjAxLDEuMzE0IC0xLjE1OCwxLjMxNGMtMS4xMzgsMCAtNi4wMzksMCAtNi4wMzksMGMwLDAgLTEuMDIzLC0wLjA5MyAtMS4wMjMsLTEuMzAzYzAsLTEuMjA3IDAsLTUuMTk2IDAsLTUuMTk2bC0zLjU0OSwtMC4yODV2Ny4wMDFjMC41NzQsMy4zNTkgMy4zMTEsMy42MTcgMy4zMTEsMy42MTdjMCwwIDAuMjc4LDAuMDIyIDAuMzI0LDAuMDI2aDguMTU2YzAsMCAzLjQ5MSwtMC4zMTEgMy40OTEsLTQuMDIzYzAuMDAxLC0zLjcxMyAwLjAwMSwtNS
40ODQgMC4wMDEsLTUuNDg0ek0xMy4xMTEsMzkuOTE0aDE1LjczYzIuOTE0LC0wLjY0NyAzLjIxOCwtMy41NzcgMy4yMTgsLTMuNTc3YzAuMTM2LC0wLjg3MSAwLjA1NywtMS41NzQgMC4wNTcsLTEuNTc0Yy0wLjA4OCwtMC41ODggLTEuMDk0LC0zLjE3OCAtMy4yODEsLTMuNDA1Yy0xLjMwNCwtMC4xMzQgLTEyLjkxLC0xLjE1NSAtMTIuOTEsLTEuMTU1YzAuMjI1LDEuMjg4IDAuNzQ4LDEuOTM4IDEuMDk0LDIuMzExYzAuODA1LDAuODU3IDIuMDg3LDEuMDk5IDIuMDg3
LDEuMDk5YzAuMzA5LDAuMDMzIDguOTQ1LDAuODI0IDguOTQ1LDAuODI0YzAuMjc0LDAuMDE3IDAuNzk3LDAuMDkzIDAuNzksMC44NDljMCwwLjA5MSAtMC4wNzUsMC43NTcgLTAuNzM4LDAuNzU3aC0xMi4wMTRjLTAuMjc2LDAgLTAuNSwtMC4yMjQgLTAuNSwtMC41di01LjM3M2wtMy40NzgsLTAuMjgxdjkuMDI3YzAsMC41NSAwLjQ0OCwwLjk5OCAxLDAuOTk4ek00Ny40NDQsMzcuMDE3YzAuMDAxLC0wLjU1MiAwLjQ0OCwtMC45OTggMSwtMC45OThoMTEuNDI5YzAuMj
g2LDAgMC41OTUsLTAuMTg3IDAuNTk1LC0wLjE4N2MwLjEzLC0wLjEyOSAwLjIzNSwtMC4zNjQgMC4yMzUsLTAuNTkxYzAsLTAuNzUzIC0wLjU2MSwtMC43ODYgLTAuODQzLC0wLjgwM2MwLDAgLTguNzMyLC0wLjgwOCAtOS4wMzYsLTAuODM0YzAsMCAtMS4yMTEsLTAuMjA3IC0yLjAxNywtMS4wNjhjLTAuMzUxLC0wLjM2OSAtMC44MTUsLTAuNzcxIC0xLjE2MSwtMi4wOTljMCwwIDExLjY3MSwwLjc2MyAxMi45NjgsMC44OTdjMi4xODksMC4yMzIgMy4yMTUsMi42MzIgMy4zMDgsMy40M2MwLDAgMC4wOTMsMC43MjIgLTAuMDIsMS42MDdjMCwwIC0wLjQ1NCwzLjM3NCAtMy42NjQsMy41NzloLTExLjc5N2MtMC41NTMsMCAtMS4wMDEsLTAuNDQ5IC0xLC0xLjAwMnoiIGZpbGw9InVybCgjY29sb3ItMikiIGlkPSJwYXRoMTEiLz48L2c+PC9nPjwvc3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Asus</friendlyname>
</Brand>
<Brand alias="Brand" id="4">
<name>Cisco</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icon-cisco.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dHA6Ly93d
3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgd2lkdGg9IjEwOCIgaGVpZ2h0PSIxMDgiIHZpZXdCb3g9IjAgMCAxMDggMTA4IiByb2xlPSJpbWciIHZlcnNpb24
9IjEuMSIgaWQ9InN2ZzExIiBzb2RpcG9kaTpkb2NuYW1lPSJpY29uLWNpc2NvLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS40LjMgKDBkMTVmNzUwNDIsIDIwMjUtMTItMjUpIj48c29kaXBvZGk6bmFtZWR2aWV3IGlkPSJuYW1lZHZpZXcxMSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9yZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlO
nBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgc2hvd2d1aWRlcz0idHJ1ZSIgaW5rc2NhcGU6em9vbT0iNi44MjI5NjAyIiBpbmtzY2FwZTpjeD0iNDguODc5MDc4IiBpbmtzY2FwZTpjeT0iNTEuNzM3MDc1IiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjI1NjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNjAiIGlua3NjYXBlOndpbmRvdy14PSIwIiBpbmtzY2FwZTp3aW5kb3cteT0iMCIgaW5rc2NhcGU6d2luZG93LW1heGl
taXplZD0iMSIgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMTEiPjxzb2RpcG9kaTpndWlkZSBwb3NpdGlvbj0iMTYuOTM5NTg3LDUzLjM3NjMwMyIgb3JpZW50YXRpb249IjAsLTEiIGlkPSJndWlkZTExIiBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIi8+PC9zb2RpcG9kaTpuYW1lZHZpZXc+PHRpdGxlIGlkPSJmdy1jLWhlYWRlcl9fbG9nby10aXRsZSI+Q2lzY28uY29tIEZyYW5jZTwvdGl0bGU+PGRlZnMgaWQ9ImRlZnMxIj48cGF0aCBkPSJtIDAsMjIuNzY5IGEgM
i4zNDgsMi4zNDggMCAwIDAgMy45MzUsMS41NDUgYyAwLjQzNCwtMC40MDMgMC43LC0wLjk1NSAwLjc0NCwtMS41NDUgdiAtNS4yIGEgMi4zNCwyLjM0IDAgMCAwIC00LjY3OSwwIHYgNS4yIiBpZD0iYmFyX3Nob3J0IiBjbGFzcz0iYmFyIi8+PHBhdGggZD0ibSAxMi45NSwyMi43NjkgYSAyLjM0OSwyLjM0OSAwIDAgMCAyLjM0LDIuMTcxIDIuMzQ2LDIuMzQ2IDAgMCAwIDIuMzM5LC0yLjE3MSBWIDExLjExMiBhIDIuMzQxLDIuMzQxIDAgMCAwIC00LjY3OSwwIFYgMjI
uNzciIGlkPSJiYXJfdGFsbCIgY2xhc3M9ImJhciIvPjxwYXRoIGQ9Im0gMjUuODMyLDI3LjQ2NCBhIDIuMzQ1LDIuMzQ1IDAgMCAwIDQuNjc4LDAgViAyLjI0OSBhIDIuMzQyLDIuMzQyIDAgMCAwIC00LjY3OCwwIHYgMjUuMjE1IiBpZD0iYmFyX2dyYW5kZSIgY2xhc3M9ImJhciIvPjxwYXRoIGQ9Im0gMjQuMDI2LDU2LjI3NyB2IC01LjAwMiBsIC0wLjA5OCwwLjA0MyBhIDkuMjUzLDkuMjUzIDAgMCAxIC0zLjYwNSwwLjkxNSA1LjMwMyw1LjMwMyAwIDAgMSAtMy42M
ywtMS4wNyA0LjY0NCw0LjY0NCAwIDAgMSAtMS41OCwtMi4yNDQgNS4zOTUsNS4zOTUgMCAwIDEgLTAuMTA2LC0zIDQuNiw0LjYgMCAwIDEgMS42MDksLTIuNTY2IDQuODIzLDQuODIzIDAgMCAxIDIuNTI4LC0xLjA5IDguMzMyLDguMzMyIDAgMCAxIDQuNzc0LDAuODk1IGwgMC4xMDgsMC4wNTYgdiAtNS4wMyBsIC0wLjIyOCwtMC4wNjEgYSAxMi43OCwxMi43OCAwIDAgMCAtNC41NTIsLTAuNTk2IDEwLjUzNCwxMC41MzQgMCAwIDAgLTQuMDY1LDAuOTMgOS4yOSw5LjI
5IDAgMCAwIC0zLjMyOSwyLjU3MiAxMC4wMTQsMTAuMDE0IDAgMCAwIC0wLjE4MiwxMi4xOCA5LjU0Niw5LjU0NiAwIDAgMCA1LjI5MiwzLjQwMyBjIDIuMjExLDAuNTM4IDQuNTI4LDAuNDU2IDYuNjk3LC0wLjIzNCBsIDAuMzY3LC0wLjEwMSIgaWQ9ImNpc2NvX2MiLz48L2RlZnM+PGcgZmlsbD0iIzAyYzhmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBpZD0iZzExIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC4wOTQ2Njg1OSwyNi4yMzQ5NDYpIj48dXNlIGhyZWY9IiNja
XNjb19jIiBpZD0idXNlMSIvPjx1c2UgaHJlZj0iI2Npc2NvX2MiIHg9IjQ5LjUiIGlkPSJ1c2UyIi8+PHBhdGggZD0ibSA0MS42OSw1Mi4xMjUgLTAuMDE5LDQuMzA4IDAuMzE1LDAuMDU0IGMgMC45ODksMC4xODUgMS45ODcsMC4zMTMgMi45OSwwLjM4NSBhIDE4LjEsMTguMSAwIDAgMCAyLjY0MiwwLjA1MSBjIDAuODQyLC0wLjA2IDEuNjc1LC0wLjIxOCAyLjQ4LC0wLjQ2OCBhIDYuODYyLDYuODYyIDAgMCAwIDIuNTczLC0xLjM3MSA1LjE5LDUuMTkgMCAwIDAgMS4
0OTgsLTIuMTQ4IDUuOTEyLDUuOTEyIDAgMCAwIC0wLjAzLC00LjMyNCA0Ljg1Miw0Ljg1MiAwIDAgMCAtMS4zNDMsLTEuODYyIDUuNTY4LDUuNTY4IDAgMCAwIC0xLjk3LC0xLjE0NyBsIC0zLjI1LC0xLjIwNiBhIDEuNzQyLDEuNzQyIDAgMCAxIC0wLjg4NywtMC44NDUgMS4xMDcsMS4xMDcgMCAwIDEgMC4wMzYsLTAuOTg2IDEuMjksMS4yOSAwIDAgMSAwLjIxNywtMC4yOTEgMS43NSwxLjc1IDAgMCAxIDAuNDgsLTAuMzQ3IGMgMC4zNjMsLTAuMTggMC43NTUsLTAuM
jkzIDEuMTU4LC0wLjMzNyBhIDYuNzYsNi43NiAwIDAgMSAyLjA3MiwwLjAyMiBjIDAuODEsMC4wODggMS42MTMsMC4yMzEgMi40MDIsMC40MyBsIDAuMTY4LDAuMDM3IHYgLTMuOTc0IGwgLTAuMzEsLTAuMDY3IGEgMjEuMTQsMjEuMTQgMCAwIDAgLTIuNDQ0LC0wLjQzNSAxMi41NDUsMTIuNTQ1IDAgMCAwIC0zLjIxMywtMC4wMTQgNi45NDUsNi45NDUgMCAwIDAgLTMuNjk5LDEuNDg4IDQuOTA4LDQuOTA4IDAgMCAwIC0xLjU4LDIuMTc4IDUuOTg0LDUuOTg0IDAgMCA
wIC0wLjAwMyw0LjA1IGMgMC4yNDIsMC42NSAwLjYzLDEuMjM3IDEuMTM2LDEuNzE0IDAuNDM3LDAuNDIyIDAuOTMyLDAuNzggMS40NywxLjA2NSAwLjcwOCwwLjM4IDEuNDU4LDAuNjc1IDIuMjM1LDAuODc4IDAuMjU3LDAuMDc3IDAuNTEyLDAuMTU4IDAuNzY2LDAuMjQzIGwgMC4zODUsMC4xNDEgMC4xMSwwLjA0NSBjIDAuMzgsMC4xMzYgMC43MjYsMC4zNSAxLjAxOCwwLjYyOCAwLjIwMiwwLjE5IDAuMzU4LDAuNDIzIDAuNDU1LDAuNjgzIDAuMDYsMC4yMzcgMC4wN
jEsMC40ODUgMC4wMDMsMC43MjMgYSAxLjUzNiwxLjUzNiAwIDAgMSAtMC43NDQsMC44OTIgMy42OTEsMy42OTEgMCAwIDEgLTEuMjM5LDAuMzg3IDksOSAwIDAgMSAtMS45MiwwLjA5NyAyMS45NzMsMjEuOTczIDAgMCAxIC0yLjUwNywtMC4zMzQgYyAtMC40MzMsLTAuMDkgLTAuODY0LC0wLjE5IC0xLjI5MSwtMC4zMDMgeiBtIC0xMS4xNDQsNC40ODIgaCA0LjczIFYgMzcuODQ2IGggLTQuNzMgeiBNIDg1LjMwNSw0My4zODYgYSA0LjkzNCw0LjkzNCAwIDEgMSA2LjE
1Nyw3LjcxMSA0LjkzNCw0LjkzNCAwIDAgMSAtNi4xNTcsLTcuNzEgbSAtNi44NjcsMy44NDggYSA5Ljg3LDkuODcgMCAwIDAgMTIuMDAyLDkuNDg1IDkuNjI5LDkuNjI5IDAgMCAwIDMuMTU3LC0xNy43MjkgOS45MzQsOS45MzQgMCAwIDAgLTE1LjE2LDguMjQ0IiBpZD0icGF0aDIiLz48dXNlIGhyZWY9IiNiYXJfc2hvcnQiIHg9IjAiIGlkPSJ1c2UzIi8+PHVzZSBocmVmPSIjYmFyX3RhbGwiIHg9IjAiIGlkPSJ1c2U0Ii8+PHVzZSBocmVmPSIjYmFyX2dyYW5kZSIge
D0iMCIgaWQ9InVzZTUiLz48dXNlIGhyZWY9IiNiYXJfdGFsbCIgeD0iMjUuODc1IiBpZD0idXNlNiIvPjx1c2UgaHJlZj0iI2Jhcl9zaG9ydCIgeD0iNTEuNzUiIGlkPSJ1c2U3Ii8+PHVzZSBocmVmPSIjYmFyX3RhbGwiIHg9IjUxLjc1IiBpZD0idXNlOCIvPjx1c2UgaHJlZj0iI2Jhcl9ncmFuZGUiIHg9IjUxLjc1IiBpZD0idXNlOSIvPjx1c2UgaHJlZj0iI2Jhcl90YWxsIiB4PSI3Ny42MjUiIGlkPSJ1c2UxMCIvPjx1c2UgaHJlZj0iI2Jhcl9zaG9ydCIgeD0iMTAzLjM3NSIgaWQ9InVzZTExIi8+PC9nPjxtZXRhZGF0YSBpZD0ibWV0YWRhdGExMSI+PHJkZjpSREY+PGNjOldvcmsgcmRmOmFib3V0PSIiPjxkYzp0aXRsZT5DaXNjby5jb20gRnJhbmNlPC9kYzp0aXRsZT48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Cisco</friendlyname>
</Brand>
<Brand alias="Brand" id="5">
<name>Dell</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-dell.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMwMjg4ZDEiIGQ9Ik0yNCw0QzEyLjk1Niw0LDQsMTIuOTU2LDQsMjRzOC45NTYsMjAsMjAsMjBzMjAtOC45NTYsMjAtMjBTMzUuMDQ0LDQsMjQs
NHogTTI0LDQxYy05LjM5MSwwLTE3LTcuNjA5LTE3LTE3UzE0LjYwOSw3LDI0LDdzMTcsNy42MDksMTcsMTdTMzMuMzkxLDQxLDI0LDQxeiIvPjxwYXRoIGZpbGw9IiMwMjg4ZDEiIGQ9Ik0zNS42NDEsMjUuNTYzbDIuODQsMC4wMDRsLTAuMDA0LDIuMzk1bC01LjY5MS0wLjAxMmwwLjAxMi04LjE3MmwyLjg1NSwwLjAwNEwzNS42NDEsMjUuNTYzeiBNMjYuMzQsMjUuMTAybC00LjY5OSwzLjY4NGwtNC4yODUtMy4zNzljLTAuNjIxLDEuNDg0LTIuMTA5LDIuNTItMy44Mz
YsMi41MTZsLTMuNjY0LTAuMDA0bDAuMDA4LTguMTcybDMuNjY4LDAuMDA0YzEuOTI2LDAuMDA0LDMuMzA5LDEuMjIzLDMuODI4LDIuNTMxbDQuMjk3LTMuMzY3bDEuNTg2LDEuMjVsLTMuOTM0LDMuMDg2bDAuNzU0LDAuNTk0bDMuOTM0LTMuMDg2bDEuNTksMS4yNTRsLTMuOTM0LDMuMDgybDAuNzUsMC41OTRsMy45NDEtMy4wODJsMC4wMDQtMi44MzZsMi44NTIsMC4wMDRsLTAuMDA4LDUuNzgxbDIuODQsMC4wMDRsLTAuMDA0LDIuMzkxbC01LjY5MS0wLjAwOEwyNi4zNCwyNS4xMDJ6IE0xNS4wMTIsMjMuODRjMC0xLjExMy0wLjczLTEuNzQyLTEuNzctMS43NDJoLTAuNjM3bC0wLjAwNCwzLjQ3N2gwLjYyMUMxNC4xODQsMjUuNTc0LDE1LjAxMiwyNS4wNTEsMTUuMDEyLDIzLjg0Ii8+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Dell</friendlyname>
</Brand>
<Brand alias="Brand" id="6">
<name>HP Inc</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-hp.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0yNCA0QTIwIDIwIDAgMSAwIDI0IDQ0QTIwIDIwIDAgMSAwIDI0IDRaIi8+PHBhdGggZmlsbD0iIzE5NzZkMiIgZD0iTTI0LDQzLj
k5N2MtMC4xOTksMC0wLjY1MiwwLjAwNi0wLjg1LDBsNC0xMC45OTloNS42MjVjMC45ODcsMCwyLjA3MS0wLjc1OSwyLjQwOS0xLjY4Nmw0Ljc0OC0xMi42ODdjMC43MjUtMS45OTUtMC40MTctMy42MjYtMi41MzktMy42MjZoLTcuODA0bC02LjUxOCwxOC4yNTdoLTAuMDAybC0zLjcxMiwxMC4xOThDMTAuNTUsNDEuMzYxLDQsMzMuNDQ1LDQsMjMuOTk5YzAtOS4xNzQsNi4xNzgtMTYuOTA1LDE0LjYtMTkuMjYxbC0zLjgzLDEwLjUyNmgtMC4wMDFMOC4xNSwzMi45OTho
NC4yMzlsNS41NzYtMTQuOTk5aDMuMTg1bC01LjU3NiwxNC45OTlsMy45MTksMC4wMDFsNS40MzgtMTQuMzc0YzAuNzI2LTEuOTk1LTAuNDE2LTMuNjI2LTIuNTM2LTMuNjI2SDE5LjE1bDMuOTUxLTEwLjk3OEMyMy4zOTksNC4wMDgsMjMuNjk5LDQsMjQsNGMxMS4wNDYsMCwyMCw4Ljk1MywyMCwxOS45OTlTMzUuMDQ2LDQzLjk5NywyNCw0My45OTd6IE0zNi4xNSwxNy45OTloLTMuMTg1bC00LjUwOSwxMS45OTloMy4xODVMMzYuMTUsMTcuOTk5eiIvPjwvc3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>HP Inc</friendlyname>
</Brand>
<Brand alias="Brand" id="7">
<name>HPE</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icon-hpe.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dHA6Ly93d3c
udzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIGlkPSJrYXRtYW5fMSIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCA2MzAgNjMwIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzb2RpcG9kaTpkb2NuYW1lPSJpY29uLWhwZS5zdmciIHdpZHRoPSI2MzAiIGhlaWdodD0iNjMwIiBpbmtzY2FwZTp2ZXJzaW9uPSIxLjQuMyAoMGQxNWY3NTA0MiwgMjAyNS0xMi0yNSkiPjxkZWZzIGlkPSJkZWZzM
iIvPjxzb2RpcG9kaTpuYW1lZHZpZXcgaWQ9Im5hbWVkdmlldzIiIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgYm9yZGVyY29sb3I9IiMwMDAwMDAiIGJvcmRlcm9wYWNpdHk9IjAuMjUiIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIyIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIiBpbmtzY2FwZTpwYWdlY2hlY2tlcmJvYXJkPSIwIiBpbmtzY2FwZTpkZXNrY29sb3I9IiNkMWQxZDEiIHNob3dndWlkZXM9InRydWUiIGlua3NjYXBlOnpvb209IjAuNjkwNTUxNSIgaW5rc2N
hcGU6Y3g9Ii0yMTcuOTQxNzUiIGlua3NjYXBlOmN5PSIyNzUuMTQyNCIgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIiBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMzYwIiBpbmtzY2FwZTp3aW5kb3cteD0iMCIgaW5rc2NhcGU6d2luZG93LXk9IjAiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImthdG1hbl8xIj48c29kaXBvZGk6Z3VpZGUgcG9zaXRpb249IjE5Ny42NjI0NCwzMTQuNDg4NDgiIG9yaWVudGF0a
W9uPSIwLC0xIiBpZD0iZ3VpZGUyIiBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIi8+PC9zb2RpcG9kaTpuYW1lZHZpZXc+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyIgaWQ9InN0eWxlMSI+Cgkuc3Qwe2ZpbGw6bm9uZTtzdHJva2U6IzAwMDAwMDtzdHJva2Utd2lkdGg6MzY7fQoJLnN0MXtmaWxsOm5vbmU7c3Ryb2tlOiMwM0E4ODM7c3Ryb2tlLXdpZHRoOjM2O30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0ibSAxOC41MTE5ODcsNDA1LjkzMDEyIHYgLTE4MCBtIDE
1NC4wMDAwMDMsMTgwIHYgLTE4MCBtIC0xNTQuMDAwMDAzLDg5IEggMTU1LjUxMTk5IG0gOTUsOTEgdiAtMTgwIG0gMCwxOCBoIDEwMiBjIDI3LjYsMCA1MCwyMi40IDUwLDUwIDAsMjcuNiAtMjIuNCw1MCAtNTAsNTAgaCAtMTAyIG0gMjIyLC02NyB2IC0zMyBoIDE1OCIgaWQ9InBhdGgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Im0gNjMwLjUxMTk5LDM4Ny45MzAxMiBoIC0xNTggdiAtNzYgaCAxNTgiIGlkPSJwYXRoMiIvPgo8L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>HPE</friendlyname>
</Brand>
<Brand alias="Brand" id="8">
<name>IBM</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-ibm.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMzZjUxYjUiIGQ9Ik00OCAxNkw0OCAxNCA0MC40NjkgMTQgMzkuODA5IDE2ek0zMyAzMUwzMyAyOSAyOSAyOSAyNyAyOSAyNyAzMXpNMzkuNzY2I
DI4TDQwLjUxIDI2IDM0LjUxIDI2IDM1LjI2NiAyOHpNMjkgMjZIMzNWMjhIMjl6TTI5IDIzSDMzVjI1SDI5ek00MiAyOUw0MiAzMSA0OCAzMSA0OCAyOSA0NiAyOXpNMzYuMTgxIDE5TDM1LjUyMSAxNyAyNyAxNyAyNyAxOSAyOSAxOXpNMzcuMTcgMjJMMzYuNTEgMjAgMjkgMjAgMjkgMjJ6TTMzLjM3OCAyM0wzNC4xMzMgMjUgNDAuODgzIDI1IDQxLjYyOCAyM3pNNDIgMjNINDZWMjVINDJ6TTI3IDMySDMzVjM0SDI3ek0zNS4xOTEgMTZMMzQuNTMxIDE0IDI3IDE0IDI
3IDE2ek0zNi43NzYgMzJMMzcuNTMxIDM0IDM4LjI3NiAzMnpNNDIgMzJINDhWMzRINDJ6TTM5LjQ3OSAxN0wzOC44MTkgMTkgNDYgMTkgNDggMTkgNDggMTd6TTM5LjM5MyAyOUwzNS42NDMgMjkgMzYuMzk4IDMxIDM4LjY0OCAzMXpNNDIgMjZINDZWMjhINDJ6TTM4LjQ5IDIwTDM3LjgzIDIyIDQ2IDIyIDQ2IDIwek0wIDE0SDhWMTZIMHpNMCAxN0g4VjE5SDB6TTIgMjBINlYyMkgyek0yIDIzSDZWMjVIMnpNMiAyNkg2VjI4SDJ6TTAgMjlIOFYzMUgwek0wIDMySDhWM
zRIMHpNMTAgMTdIMThWMTlIMTB6TTI0Ljk3NyAxNmMtLjkxMy0xLjIwOC0yLjM0Ny0yLTMuOTc3LTJIMTB2Mmg3LjAyM0gyNC45Nzd6Ii8+PHBhdGggZmlsbD0iIzNmNTFiNSIgZD0iTTI1LjU3OCAxN2gtOS4xMzFDMTYuMTcxIDE3LjYxMyAxNiAxOC4yODMgMTYgMTloMTBDMjYgMTguMjg4IDI1Ljg0NiAxNy42MTMgMjUuNTc4IDE3ek0yMy45NzUgMjNIMTJ2MmgxMS45NzNjLS44MzMtLjYyLTEuODU0LTEtMi45NzMtMUMyMi4xMTkgMjQgMjMuMTQyIDIzLjYyMSAyMy4
5NzUgMjN6TTE3LjAyMyAzMkgxMHYyaDExYzEuNjMgMCAzLjA2NS0uNzkyIDMuOTc3LTJIMTcuMDIzek0xOCAyOWgtMi02djJoNi40NDdIMThoNy41NzhDMjUuODQ2IDMwLjM4NyAyNiAyOS43MTIgMjYgMjlIMTh6TTIxIDIwYzAgMCAwIC4wODMgMCAxcy0xIDEtMSAxaDQuOTc5Yy40NDEtLjU4NC43Ny0xLjI1Ny45MjEtMkgyMXpNMTIgMjBIMTdWMjJIMTJ6Ii8+PGc+PHBhdGggZmlsbD0iIzNmNTFiNSIgZD0iTTIxIDI4aDQuODg1Yy0uMTU2LS43MzgtLjQ2Ny0xLjQxOC0uOTA3LTJIMjBjMCAwIDEgLjE2NyAxIDFTMjEgMjggMjEgMjh6TTEyIDI2SDE3VjI4SDEyeiIvPjwvZz48L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>IBM</friendlyname>
</Brand>
<Brand alias="Brand" id="9">
<name>Lenovo</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-lenovo.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSIxNiIgeT0iMTYiIGZpbGw9IiNmZjE3NDQiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTEuOTM1LDI2LjA2MmMwLjM3LD
AuMzQxLDAuNzgyLDAuNDUsMS4yMjcsMC40NzhjMC42NDUsMC4wMzksMS4yMTctMC4xNTYsMS43MjQtMC41NDYgYzAuMTI0LTAuMDk2LDAuMTYzLTAuMTI2LDAuMTYzLTAuMTI2czAuNzc3LDAuNjA5LDEuMDk3LDAuODU1Yy0wLjI2MSwwLjMwOS0wLjU2NywwLjUyMS0wLjkwMSwwLjY5MiBjLTEuMTAzLDAuNTY1LTIuMjQ5LDAuNjg3LTMuNDI0LDAuMjY0Yy0xLjM0Ni0wLjQ4NS0yLjEzMS0xLjY5My0yLjA1OS0zLjExN2MwLjA3My0xLjQ0MSwxLjAwNS0yLjYwOCwyLjM5
Mi0yLjk0NCBjMS4wNjQtMC4yNTcsMi4wODQtMC4xNDMsMi45OCwwLjUzOWMwLjY1MSwwLjQ5NiwxLjAwMSwxLjI4LDEuMTQ3LDIuMDY4YzAsMC0yLjU5NSwxLjExLTMuNzk1LDEuNjA2IEMxMi4zMTMsMjUuOTAzLDEyLjE0MSwyNS45NzUsMTEuOTM1LDI2LjA2MnogTTExLjQ3MiwyNC45MjhjMC45NjktMC40MDEsMS45MzUtMC44MDEsMi45MDEtMS4yMDEgYy0wLjMzNC0wLjcyMi0xLjA5Ni0xLjAxNy0xLjg2Ni0wLjc0OEMxMS43NTgsMjMuMjQsMTEuMjgsMjQuMTI0LD
ExLjQ3MiwyNC45Mjh6Ii8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTI3LjA3NiwyNy45MzRjLTEuNjMyLTAuMDE3LTIuOTU2LTEuMDY4LTMuMjYxLTIuNmMtMC4zNy0xLjg1MiwwLjk2OS0zLjYzMywyLjg2LTMuODA4IGMxLjI4MS0wLjExOCwyLjM3MywwLjI1NCwzLjE1NSwxLjNjMS40NTEsMS45NDEsMC4yMiw0Ljc1Ny0yLjE5Myw1LjA1NUMyNy40NSwyNy45MDUsMjcuMjYzLDI3LjkxNywyNy4wNzYsMjcuOTM0eiBNMjcuMTEsMjYuNDM0IGMwLjkyOSwwLjAwMiwxLjYy
Mi0wLjcyMywxLjYyOC0xLjcwNGMwLjAwNi0wLjk3LTAuNzI0LTEuNzQyLTEuNjQ5LTEuNzQ1Yy0wLjkzNi0wLjAwMy0xLjYzMSwwLjczNC0xLjYyOCwxLjcyNiBDMjUuNDY1LDI1LjY3NSwyNi4xODksMjYuNDMyLDI3LjExLDI2LjQzNHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNDAuNjI0LDI3LjkzNGMtMS42MzItMC4wMTctMi45NTYtMS4wNjgtMy4yNjEtMi42Yy0wLjM3LTEuODUyLDAuOTY5LTMuNjMzLDIuODYtMy44MDggYzEuMjgxLTAuMTE4LDIuMzczLDAuMj
U0LDMuMTU1LDEuM2MxLjQ1MSwxLjk0MSwwLjIyLDQuNzU3LTIuMTkzLDUuMDU1QzQwLjk5OCwyNy45MDUsNDAuODExLDI3LjkxNyw0MC42MjQsMjcuOTM0eiBNNDAuNjU4LDI2LjQzNGMwLjkyOSwwLjAwMiwxLjYyMy0wLjcyMywxLjYyOC0xLjcwNGMwLjAwNi0wLjk3LTAuNzI0LTEuNzQyLTEuNjQ5LTEuNzQ1Yy0wLjkzNi0wLjAwMy0xLjYzMSwwLjczNC0xLjYyOCwxLjcyNiBDMzkuMDEzLDI1LjY3NSwzOS43MzcsMjYuNDMyLDQwLjY1OCwyNi40MzR6Ii8+PHBhdGgg
ZmlsbD0iI2ZmZiIgZD0iTTIxLjM3NywyNy45ODdjMC0wLjA5NSwwLjAwMS0yLjU4NywwLTMuNjYzYy0wLjAwMS0wLjc1OS0wLjYwNS0xLjMyNy0xLjQxNC0xLjMzMSBjLTAuNzk0LTAuMDA1LTEuMzgzLDAuNTYtMS4zODQsMS4zMzJjLTAuMDAxLDEuMDc2LDAsMy42NzksMCwzLjY3OWwtMS43NDEsMC4wMDJsMC4wMDctNi4zNzhjMCwwLDEuMTY4LTAuMDE4LDEuNzIyLTAuMDE4IGMwLDAuMjY0LTAuMDA2LDAuODMyLTAuMDA2LDAuODMyczAuMTM4LTAuMTI4LDAuMTgxLT
AuMTcxYzEuMTU3LTEuMTc0LDMuMjI2LTAuOTczLDQuMDMxLDAuMzkxIGMwLjIyMywwLjM3OCwwLjMzOCwwLjc4OSwwLjM0LDEuMjIzYzAuMDA4LDEuMjY0LDAuMDAzLDQuMTA0LDAuMDAzLDQuMTA0UzIxLjk2NCwyNy45ODcsMjEuMzc3LDI3Ljk4N3oiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMzAuMTY0LDIxLjYwOGMwLjY0MiwwLDEuOTY0LDAuMDE1LDEuOTY0LDAuMDE1czEuNDc4LDQuMDI0LDEuNTI2LDQuMTQ5IGMwLjExNS0wLjMxMSwxLjIwOC0zLjI5LDEuNTIx
LTQuMTc0YzAuNjQ2LDAuMDE4LDEuMjg4LDAuMDEsMS45NywwLjAxYy0wLjAyOSwwLjA4NC0yLjU2Miw2LjM5OC0yLjU2Miw2LjM5OGwtMS44NzYtMC4wMDMgQzMxLjkwNSwyNi4wNDIsMzAuMTkxLDIxLjY5MiwzMC4xNjQsMjEuNjA4eiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik01Ljc2NywyNi4zOTNjMC4xMDQsMCwzLjg2OCwwLjAxMSwzLjg2OCwwLjAxMWwtMC4wMDIsMS41ODFMNCwyNy45ODl2LTguMDczaDEuNzcgQzUuNzcsMTkuOTE2LDUuNzY3LDI2LjI4NCw1Ljc2NywyNi4zOTN6Ii8+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Lenovo</friendlyname>
</Brand>
<Brand alias="Brand" id="10">
<name>Razer</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-razer.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiM2NGRkMTciIGQ9Ik0yNiwyMGMwLjEsMCwwLjIsMCwwLjMsMGMwLjMtMC4xLDAuNS0wLjMsMC42LTAuNWMwLjEtMC4yLDAuMS0wLjUsMC4xLTA
uOGMtMC4yLTAuNi0xLTEuOC0yLTIuNCBjMCwwLjcsMCwxLjMsMCwxLjljMCwwLjUsMCwxLDAsMS4yYzAuMSwwLjIsMC4zLDAuNCwwLjUsMC42QzI1LjcsMjAsMjUuOCwyMCwyNiwyMCBNMjkuNCwyM2MwLjcsMCwxLjYtMC4xLDIuMy0wLjUgYy0wLjUtMC4zLTEtMC42LTEuNS0wLjljLTAuNC0wLjMtMC45LTAuNi0xLjEtMC42YzAsMC0wLjEsMC0wLjEsMGMtMC4yLDAtMC40LDAuMS0wLjYsMC4yYy0wLjIsMC4xLTAuNCwwLjQtMC40LDAuNiBjLTAuMSwwLjUsMC4zLDEuM
SwwLjgsMS4yQzI5LDIzLDI5LjIsMjMsMjkuNCwyMyBNMjMsMjQuOWMwLjUtMC4yLDEtMC40LDEuNS0wLjZjMC41LTAuMiwxLTAuNCwxLjItMC41YzAuMi0wLjIsMC4zLTAuNCwwLjMtMC43IGMwLTAuMy0wLjEtMC41LTAuMy0wLjdDMjUuNiwyMi4xLDI1LjMsMjIsMjUsMjJjLTAuMiwwLTAuNSwwLjEtMC43LDAuM0MyMy45LDIyLjYsMjMuMiwyMy44LDIzLDI0LjkgTTQxLjUsMSBjLTAuNywwLTEuNCwwLjUtMS41LDEuM2MwLDAsMCwwLDAsMEMzOS43LDIuMSwzOS40LDI
sMzksMmMtMS43LDAtMi45LDAuMi0zLjYsMC43QzM0LjUsMy4yLDM0LDQuMSwzNCw1YzAsMC4xLDAsMC4xLDAsMC4yIEMzMy42LDUuMSwzMy4xLDUsMzIuNyw1Yy0xLjMsMC0yLjQsMC43LTMuMSwyQzI5LjIsNy43LDI5LDguNCwyOSw5LjJjMCwyLjYsMi4yLDQuNiw0LjUsNi42YzIuNywyLjQsMy45LDMuOCwzLjMsNC44IGMtMC4yLDAuNC0wLjQsMC40LTAuNCwwLjRjLTAuMSwwLTAuMiwwLTAuMywwYy0wLjEsMC0wLjMsMC0wLjUtMC4xYzAtMC42LTAuMS0xLjEtMC4yL
TEuNmMtMC4yLTAuNi0wLjUtMS4yLTEtMS43IGMtMC40LTAuNS0xLTAuNy0xLjUtMC45Yy0wLjEsMC0wLjItMC4xLTAuNC0wLjFjLTAuMywwLTAuNywwLjItMC44LDAuNWMtMC4zLDAuNC0wLjIsMC45LDAuMiwxLjNjMC4yLDAuMiwwLjQsMC40LDAuNSwwLjYgYzAuMSwwLjIsMC4xLDAuMywwLjEsMC41Yy0wLjItMC4xLTAuNS0wLjMtMC43LTAuNGMtMC44LTAuNS0xLjQtMC45LTEuOS0xYzAtMC4xLTAuMS0wLjItMC4xLTAuM2MtMC41LTEuNS0yLjEtMy43LTQuMy00LjU
gYy0xLTMuNS0zLjMtNC4zLTUuMS00LjNjLTQuNiwwLTUuNCw0LjktNiw4LjVjLTAuMiwxLjQtMC43LDQtMS4zLDQuNWMwLTAuMi0wLjEtMC41LTAuMS0xQzEzLDE5LjksMTIuNywxNywxMCwxNyBjLTEuNiwwLTIuNCwxLjEtMi44LDEuN2MtMC4yLTAuMi0wLjMtMC40LTAuNC0wLjZjLTAuMy0wLjYtMS0xLjEtMS43LTEuMUM1LjEsMTYuOSw1LDE2LjcsNSwxNi41QzUsMTUuNyw0LjMsMTUsMy41LDE1IGMtMC43LDAtMS4yLDAuNC0xLjQsMS4xQzEuNCwxNi4zLDEsMTYuO
CwxLDE3LjVDMSwxOC4zLDEuNywxOSwyLjUsMTljMC4xLDAsMC4yLDAsMC4zLDBDMi45LDE5LjEsMywxOS4xLDMsMTkuMiBjMCwwLjIsMC4xLDAuNSwwLjIsMC43YzEsMS45LDIuNSwyLjcsMywyLjlDNi42LDIyLjksNywyMyw3LjQsMjNjMC43LDAsMS4zLTAuMiwxLjgtMC41QzkuNSwyNCwxMC4zLDI2LDEzLDI2IGM0LjEsMCw0LjktNC42LDUuNC03LjljMC42LTMuNCwxLTUuMSwyLTUuMWMwLjMsMCwwLjcsMCwxLjEsMC45Yy0wLjQsMC4yLTAuNywwLjUtMSwwLjhjLTA
uNSwwLjUtMC44LDEuMS0xLDEuNyBjLTAuMiwwLjYtMC4xLDEuMi0wLjEsMS43YzAuMSwwLjUsMC41LDAuOCwwLjksMC45YzAsMCwwLDAsMC4xLDBjMC41LDAsMC45LTAuMywxLTAuOGMwLjEtMC4zLDAuMi0wLjYsMC4zLTAuOCBjMC4xLTAuMSwwLjItMC4yLDAuMy0wLjNjMCwwLjMsMCwwLjYsMCwwLjljMCwwLjksMCwxLjUsMC4xLDJjLTEsMS0yLjIsMy0yLjIsNS4yYy0xLjMsMC45LTIuMiwxLjktMi43LDNjLTAuNSwxLjItMC41LDIuNSwwLjEsMy43IGMwLjgsMS45L
DIuNSwyLjksNC45LDIuOWMxLjgsMCwzLjgtMC41LDUuNy0xLjFjMS43LTAuNSwzLjMtMC45LDQuMy0wLjljMC4yLDAsMC40LDAsMC42LDAuMWMtMC4yLDAuMS0wLjUsMC4zLTEsMC42IGMtMS4xLDAuNi0zLjYsMi0yLjUsNC41YzAuNywxLjYsMi41LDEuOCwzLjYsMS44bDAuMSwwYzAsMCwwLDAsMCwwYy0wLjEsMC4yLTAuMiwwLjMtMC40LDAuNmMtMC40LDAuNC0wLjYsMC44LTAuNiwxLjMgYy0wLjEsMC0wLjMsMC4xLTAuNSwwLjFjLTAuOCwwLTEuNSwwLjctMS41LDE
uNWMwLDAuNywwLjQsMS4yLDEuMSwxLjRjMC4yLDAuNiwwLjgsMS4xLDEuNCwxLjFjMC44LDAsMS41LTAuNywxLjUtMS41bDAtMC4zIGMwLjEtMC4xLDAuMS0wLjEsMC4yLTAuMmMwLjUsMCwwLjktMC4yLDEuMi0wLjZjMS43LTEuNywxLjYtMy4zLDEuNi00LjFjMC0xLjMtMC45LTIuNC0yLTIuOWMxLjMtMC45LDIuNy0yLjUsMS42LTQuOCBjLTAuOC0xLjctMi4yLTIuNi00LjQtMi42Yy0xLjcsMC0zLjUsMC41LTUuMywxYy0xLjgsMC41LTMuNCwwLjktNC42LDAuOWMtM
SwwLTEuMS0wLjMtMS4yLTAuNUMyMSwzMC4xLDIxLDI5LjksMjEsMjkuOCBjMC4xLTAuMiwwLjMtMC41LDAuOC0wLjljMC40LDAuNCwwLjksMC42LDEuMywwLjhjMC40LDAuMiwwLjksMC4zLDEuNCwwLjNjMC4yLDAsMC40LDAsMC42LTAuMWMwLjYtMC4xLDEuMi0wLjQsMS42LTAuNyBjMC40LTAuMywwLjYtMC44LDAuNC0xLjJjLTAuMS0wLjQtMC41LTAuNi0wLjktMC42Yy0wLjEsMC0wLjEsMC0wLjIsMGMtMC4yLDAtMC40LDAuMS0wLjYsMC4xYy0wLjEsMC0wLjIsMC0
wLjIsMCBjLTAuMiwwLTAuMy0wLjEtMC40LTAuMmMwLjItMC4xLDAuNS0wLjIsMC43LTAuM2MxLTAuNCwxLjYtMC42LDItMWMwLjEtMC4xLDAuMS0wLjEsMC4yLTAuMmMwLjEsMCwwLjMsMC4xLDAuNCwwLjEgQzI4LjYsMjYsMjksMjYsMjkuNCwyNmMwLjksMCwyLjktMC4xLDQuNS0xLjRjMC44LDAuMiwxLjUsMC40LDIuMiwwLjRjMC40LDAsMC45LTAuMSwxLjMtMC4yYzEuMi0wLjMsMi4zLTEuMSwyLjktMi4zIGMyLjItMy45LTEuMy03LjEtNC4yLTkuN0MzNC45LDExL
jcsMzMsMTAsMzMsOS4xYzAsMCwwLDAsMC0wLjFjMC4yLDAuMSwwLjQsMC4xLDAuOCwwLjNjMC42LDAuMiwxLjUsMC42LDIuNCwwLjYgYzEuMSwwLDEuOS0wLjUsMi41LTEuNWMwLjYtMSwwLjQtMS45LDAuMS0yLjVjMC4xLDAsMC4yLDAsMC4zLDBjMC42LDAsMS4yLTAuMywxLjYtMC44QzQxLjMsNS4xLDQyLDUsNDIuNSw1QzQzLjMsNSw0NCw0LjMsNDQsMy41IGMwLTAuNy0wLjQtMS4yLTEuMS0xLjRDNDIuNywxLjQsNDIuMiwxLDQxLjUsMUw0MS41LDF6Ii8+PHBhdGg
gZD0iTTEzLDI1Yy0yLjYsMC0yLjgtMi41LTIuOS0zLjhjMC0wLjMtMC4xLTAuOS0wLjItMS4xYy0wLjEsMC4xLTAuMSwwLjItMC4yLDAuM2MtMC4xLDAuMS0wLjIsMC4zLTAuMywwLjUgYy0wLjYsMS0xLjksMS40LTIuOSwxYy0wLjgtMC4zLTEuOC0xLjEtMi41LTIuNGMtMC4yLTAuNSwwLTEuMSwwLjQtMS4zYzAuNS0wLjIsMS4xLDAsMS4zLDAuNGMwLjQsMC43LDEsMS4zLDEuNCwxLjQgYzAuMiwwLjEsMC40LDAsMC41LTAuMmMwLjEtMC4xLDAuMi0wLjMsMC4yLTAuN
GMwLjMtMC42LDAuOC0xLjQsMi0xLjRjMS44LDAsMiwxLjksMi4xLDNjMC4yLDEuOCwwLjQsMiwwLjksMiBjMS41LDAsMS45LTIuMSwyLjUtNS40YzAuNi0zLjQsMS4zLTcuNiw1LTcuNmMyLjcsMCwzLjgsMS45LDQuMiw0LjFjMi4xLDAuNCwzLjcsMi43LDQuMSw0YzAuMiwwLjgsMC4yLDEuNi0wLjIsMi4zcy0xLDEuMi0xLjcsMS41IGMtMC44LDAuMi0xLjYsMC4yLTIuMy0wLjJjLTAuNy0wLjQtMS4yLTEtMS41LTEuN0MyMywxOS42LDIzLDE5LjEsMjMsMTguMmMwLTM
uNy0wLjQtNi4yLTIuNi02LjJjLTEuOSwwLTIuNCwyLjQtMyw2IEMxNi45LDIxLjMsMTYuMywyNSwxMywyNXogTTI1LDE2LjNjMCwwLjcsMCwxLjMsMCwxLjljMCwwLjUsMCwxLDAsMS4yYzAuMSwwLjIsMC4zLDAuNCwwLjUsMC42YzAuMiwwLjEsMC41LDAuMSwwLjgsMC4xIGMwLjMtMC4xLDAuNS0wLjMsMC42LTAuNWMwLjEtMC4yLDAuMS0wLjUsMC4xLTAuOEMyNi44LDE4LjEsMjYsMTYuOSwyNSwxNi4zeiIvPjxwYXRoIGQ9Ik0yNCAxNmMtLjMtLjEtLjctLjEtMS4xL
S4xLS40IDAtLjcuMS0xLjEuMi0uMy4xLS42LjQtLjkuNy0uMy4zLS40LjctLjUgMS4xLS4xLS40LS4xLS45IDAtMS40LjEtLjUuNC0uOS43LTEuMy40LS40LjgtLjcgMS4yLS45LjUtLjIuOS0uNCAxLjUtLjVsLjEgMGMuNi0uMSAxLjEuMyAxLjIuOFMyNSAxNS45IDI0LjUgMTZDMjQuMyAxNiAyNC4xIDE2IDI0IDE2ek0zLjUgMTguMWMtLjEgMC0uMSAwLS4yIDBDMy4xIDE4IDIuOCAxOCAyLjUgMTggMi4yIDE4IDIgMTcuOCAyIDE3LjVTMi4yIDE3IDIuNSAxN2MuNSA
wIC44IDAgMS4yLjJDNCAxNy4zIDQuMSAxNy42IDQgMTcuOCAzLjkgMTggMy43IDE4LjEgMy41IDE4LjF6Ii8+PHBhdGggZD0iTTQuNSAxOWMtLjEgMC0uMSAwLS4yLS4xLS4xIDAtMS4zLS43LTEuMy0yLjRDMyAxNi4yIDMuMiAxNiAzLjUgMTZTNCAxNi4yIDQgMTYuNWMwIDEuMS43IDEuNS43IDEuNi4yLjEuMy40LjIuN0M0LjkgMTguOSA0LjcgMTkgNC41IDE5ek0zNCA0M2MtLjMgMC0uNS0uMS0uNy0uMy0uNC0uNC0uNC0xIDAtMS40LjctLjcuNy0xLjQuNy0xLjggM
C0uMi0uMi0uMy0uNC0uNC0uMiAwLS40IDAtLjctLjEtMS0uMS0yLjMtLjItMi44LTEuMi0uNy0xLjcgMS0yLjYgMi4xLTMuMiAxLjctLjkgMS45LTEuMiAxLjYtMS44LS42LTEuMy0yLjgtLjgtNi4yLjEtMy43IDEtNy44IDIuMi05LjMtMS4zLS40LTEtLjUtMi0uMS0yLjkuNS0xLjIgMS42LTIuMSAyLjgtMi44LS4zLTIuMSAxLTQuMyAyLTUuMSAxLjItMS4xIDMuMS0xIDQuMi4yIDEuMSAxLjIgMSAzLjEtLjIgNC4yLS4zLjMtLjguNS0xLjcuOS0uNi4zLTEuNS42LTI
uMyAxLS4xLjEtLjIuMi0uMy4yLS4xIDAtLjEuMS0uMi4xLTEgLjYtMiAxLjMtMi4zIDIuMS0uMi40LS4yLjkuMSAxLjQuOCAxLjcgMy4zIDEuMiA3IC4yIDMuNC0uOSA3LjItMiA4LjYgMSAxIDIuMy0xLjIgMy42LTIuNSA0LjMtLjMuMi0uOC40LTEgLjYuMyAwIC42LjEuOS4xLjMgMCAuNiAwIC44LjEgMS4yLjIgMi4xIDEuMiAyLjEgMi4zIDAgLjYuMSAyLTEuMyAzLjNDMzQuNSA0Mi45IDM0LjMgNDMgMzQgNDN6TTI1IDIyYy0uMiAwLS41LjEtLjcuMy0uNC40LTEuM
iAxLjUtMS4zIDIuNi41LS4yIDEtLjQgMS41LS42LjUtLjIgMS0uNCAxLjItLjUuNC0uMy40LTEgMC0xLjRDMjUuNSAyMi4xIDI1LjMgMjIgMjUgMjJ6Ii8+PHBhdGggZD0iTTIzLjIgMjYuMWMwIC4zLjIuNy4zIDEgLjIuMy4zLjYuNi45LjIuMy42LjQgMSAuNS40LjEuOC4xIDEuMiAwLS40LjItLjguNS0xLjIuNS0uNS4xLTEgMC0xLjUtLjItLjUtLjItLjktLjUtMS4zLS44LS40LS40LS43LS43LTEtMS4ybC0uMS0uMWMtLjMtLjUtLjEtMS4xLjQtMS40LjUtLjMgMS4
xLS4xIDEuNC40QzIzLjIgMjUuOCAyMy4yIDI1LjkgMjMuMiAyNi4xek0zMi41IDQ1Yy0uMyAwLS41LS4yLS41LS41bDAtLjVjMC0uMiAwLS40IDAtLjYgMC0uMy4zLS41LjUtLjUuMyAwIC41LjIuNS41IDAgLjIgMCAuMyAwIC41bDAgLjVDMzMgNDQuOCAzMi44IDQ1IDMyLjUgNDV6Ii8+PHBhdGggZD0iTTMxLjUgNDRjLS4zIDAtLjUtLjItLjUtLjVzLjItLjUuNS0uNWMxLjEgMCAxLjUtLjcgMS42LS43LjEtLjIuNC0uMy43LS4yLjIuMS4zLjQuMi43QzMzLjkgNDIuO
CAzMy4zIDQ0IDMxLjUgNDR6TTI5LjQgMjVjLS40IDAtLjcgMC0xLS4xLTEuNi0uMy0yLjctMS45LTIuNC0zLjUuMi0uOC42LTEuNSAxLjMtMS45LjctLjQgMS41LS42IDIuMy0uNS40LjEuOC4zIDEuNy45LjYuNCAxLjQuOCAyLjIgMS4yIDAgMCAwIDAgMCAwIC4yIDAgLjMgMCAuNS4xLjEuMS4yLjEuMy4yLjkuNCAxLjguNiAyLjQuNC40LS4xLjgtLjQgMS4xLS45IDEtMS43LS44LTMuNS0zLjUtNkMzMiAxMy4xIDMwIDExLjMgMzAgOS4yYzAtLjYuMS0xLjIuNC0xLjd
DMzEuMSA2LjMgMzIgNiAzMi43IDZjLjggMCAxLjYuMyAyLjMuNi4yLjEuNi4yLjguMyAwIDAgMCAwIDAgMC0uMi0uMi0uMy0uNC0uNS0uN0MzNS4xIDUuOCAzNSA1LjQgMzUgNWMwLS42LjMtMS4xLjktMS41QzM2LjYgMy4xIDM4LjEgMyAzOSAzYy42IDAgMSAuNCAxIDFzLS40IDEtMSAxYy0uOCAwLTEuNi4xLTIgLjIgMCAwIDAgMCAwIDAgLjEuMi4yLjQuMy41QzM3LjggNi4yIDM4LjMgNyAzNy44IDhjLS45IDEuNi0yLjUuOS0zLjYuNEMzMy43IDguMiAzMy4xIDggM
zIuNyA4Yy0uMSAwLS4zIDAtLjYuNEMzMiA4LjYgMzIgOC45IDMyIDkuMWMwIDEuMyAxLjggMi45IDMuNSA0LjQgMi43IDIuNCA1LjcgNS4yIDQgOC40LS41IDEtMS4zIDEuNi0yLjMgMS45LTEuMS4zLTIuMy4xLTMuNC0uNEMzMi42IDI0LjYgMzAuOCAyNSAyOS40IDI1ek0yOSAyMWMtLjIgMC0uNC4xLS42LjItLjIuMS0uNC40LS40LjYtLjEuNS4zIDEuMS44IDEuMi41LjEgMS45LjEgMi45LS41LS41LS4zLTEtLjYtMS41LS45LS40LS4zLS45LS42LTEuMS0uNkMyOS4
xIDIxIDI5LjEgMjEgMjkgMjF6Ii8+PHBhdGggZD0iTTMyLjYgMjEuN2MuMi0uMi40LS42LjYtLjkuMi0uMy4zLS43LjMtMS4xIDAtLjQgMC0uNy0uMi0xLjEtLjEtLjQtLjQtLjctLjgtMSAuNC4yLjguMyAxLjIuNy4zLjMuNi44LjggMS4zLjEuNS4yIDEgLjIgMS41IDAgLjUtLjEgMS0uMyAxLjVsMCAuMWMtLjIuNS0uOC44LTEuMy42cy0uOC0uOC0uNi0xLjNDMzIuNCAyMS45IDMyLjUgMjEuOCAzMi42IDIxLjd6TTQwLjggNC4xYy0uMiAwLS40LS4yLS41LS40IDAtL
jMuMS0uNS40LS42LjEgMCAuMi0uMi4yLS42QzQxIDIuMiA0MS4yIDIgNDEuNSAyUzQyIDIuMiA0MiAyLjVDNDIgMy4zIDQxLjUgNCA0MC44IDQuMSA0MC45IDQuMSA0MC45IDQuMSA0MC44IDQuMXoiLz48cGF0aCBkPSJNMzksNC41Yy0wLjIsMC0wLjQtMC4yLTAuNS0wLjRjLTAuMS0wLjMsMC4xLTAuNSwwLjQtMC42QzM5LDMuNSw0MSwzLDQyLjUsM0M0Mi44LDMsNDMsMy4yLDQzLDMuNVM0Mi44LDQsNDIuNSw0IGMtMS40LDAtMy40LDAuNS0zLjQsMC41QzM5LjEsNC41LDM5LDQuNSwzOSw0LjV6Ii8+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Razer</friendlyname>
</Brand>
<Brand alias="Brand" id="11">
<name>Samsung</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-samsung.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMwZDQ3YTEiIGQ9Ik00Ny45NywxOS44MjZjMC42NTQsMy43NDctOS41NDcsOC42NTUtMjIuNzg4LDEwLjk2Yy0xMy4yMzgsMi4zMDYtMjQuN
SwxLjEzNi0yNS4xNTMtMi42MTMgYy0wLjY1My0zLjc0Nyw5LjU1MS04LjY1NCwyMi43OS0xMC45NThDMzYuMDU5LDE0LjkwNyw0Ny4zMTgsMTYuMDc4LDQ3Ljk3LDE5LjgyNnoiLz48cG9seWdvbiBmaWxsPSIjZmFmYWZhIiBwb2ludHM9IjM1LjUxLDI1LjM4OCAzNS40NDIsMjEuNDkyIDM2LjY3MSwyMS40OTIgMzYuNjcxLDI2LjQwMyAzNC45MDUsMjYuNDAzIDMzLjY3OCwyMi4zNzMgMzMuNjUyLDIyLjM3MyAzMy43MiwyNi40MDMgMzIuNDk5LDI2LjQwMyAzMi40OTk
sMjEuNDkyIDM0LjM0MiwyMS40OTIgMzUuNDgzLDI1LjM4OCIvPjxwb2x5Z29uIGZpbGw9IiNmYWZhZmEiIHBvaW50cz0iMTMuMTc3LDIxLjk1MiAxMi40OTcsMjYuNDU1IDExLjE1NywyNi40NTUgMTIuMDc2LDIxLjQ5MiAxNC4yODQsMjEuNDkyIDE1LjIwMSwyNi40NTUgMTMuODY1LDI2LjQ1NSAxMy4yMDQsMjEuOTUyIi8+PHBvbHlnb24gZmlsbD0iI2ZhZmFmYSIgcG9pbnRzPSIxOC45NjQsMjUuMjg2IDE5LjU3NywyMS40OTIgMjEuNjAxLDIxLjQ5MiAyMS43MDgsM
jYuNDU1IDIwLjQ2OCwyNi40NTUgMjAuNDM1LDIxLjk5MyAyMC40MDksMjEuOTkzIDE5LjU4LDI2LjQ1NSAxOC4zMjEsMjYuNDU1IDE3LjQ5LDIxLjk5MyAxNy40NjQsMjEuOTkzIDE3LjQzMywyNi40NTUgMTYuMTksMjYuNDU1IDE2LjMsMjEuNDkyIDE4LjMyNSwyMS40OTIgMTguOTM3LDI1LjI4NiIvPjxwYXRoIGZpbGw9IiNmYWZhZmEiIGQ9Ik05LjA2NywyNS4wNTVjMC4wNDksMC4xMiwwLjAzNCwwLjI3NSwwLjAxMSwwLjM2OGMtMC4wNDIsMC4xNjUtMC4xNTQsMC4
zMzMtMC40ODMsMC4zMzMgYy0wLjMxMiwwLTAuNS0wLjE3OS0wLjUtMC40NXYtMC40OEg2Ljc2M0w2Ljc2MiwyNS4yMWMwLDEuMTA2LDAuODcxLDEuNDQxLDEuODA1LDEuNDQxYzAuODk4LDAsMS42MzctMC4zMDcsMS43NTQtMS4xMzQgYzAuMDYxLTAuNDI5LDAuMDE1LTAuNzA5LTAuMDA1LTAuODE2Yy0wLjIwOS0xLjAzOS0yLjA5My0xLjM0OS0yLjIzMy0xLjkzYy0wLjAyNC0wLjA5OS0wLjAxNy0wLjIwNS0wLjAwNS0wLjI2MiBjMC4wMzUtMC4xNTgsMC4xNDMtMC4zM
zIsMC40NTMtMC4zMzJjMC4yOSwwLDAuNDYxLDAuMTgsMC40NjEsMC40NWMwLDAuMDkxLDAsMC4zMDcsMCwwLjMwN2gxLjIzN3YtMC4zNDggYzAtMS4wODEtMC45Ny0xLjI1LTEuNjczLTEuMjVjLTAuODgzLDAtMS42MDQsMC4yOTItMS43MzYsMS4wOTljLTAuMDM2LDAuMjIzLTAuMDQxLDAuNDIyLDAuMDExLDAuNjcxIEM3LjA0OSwyNC4xMTgsOC44MTEsMjQuNDEyLDkuMDY3LDI1LjA1NXoiLz48cGF0aCBmaWxsPSIjZmFmYWZhIiBkPSJNMjUuMjA0LDI1LjA0NmMwLjA
0OSwwLjExOSwwLjAzMywwLjI3LDAuMDExLDAuMzYzYy0wLjA0MSwwLjE2NS0wLjE1MiwwLjMzLTAuNDc5LDAuMzMgYy0wLjMwNywwLTAuNDk0LTAuMTc5LTAuNDk0LTAuNDQ0bC0wLjAwMS0wLjQ3NmgtMS4zMThsLTAuMDAyLDAuMzc5YzAsMS4wOTUsMC44NjMsMS40MjYsMS43ODcsMS40MjYgYzAuODg4LDAsMS42Mi0wLjMwMywxLjczNi0xLjEyMmMwLjA2MS0wLjQyNiwwLjAxOC0wLjcwMi0wLjAwNC0wLjgwN2MtMC4yMDgtMS4wMjktMi4wNzMtMS4zMzYtMi4yMTEtM
S45MTIgYy0wLjAyNC0wLjA5OS0wLjAxNy0wLjIwMy0wLjAwNS0wLjI1N2MwLjAzNi0wLjE2LDAuMTQyLTAuMzI5LDAuNDQ5LTAuMzI5YzAuMjg4LDAsMC40NTUsMC4xNzUsMC40NTUsMC40NDQgYzAsMC4wOSwwLDAuMzA0LDAsMC4zMDRoMS4yMjh2LTAuMzQ1YzAtMS4wNy0wLjk2Mi0xLjIzNy0xLjY1OS0xLjIzN2MtMC44NzMsMC0xLjU4OCwwLjI4OC0xLjcxNywxLjA5IGMtMC4wMzYsMC4yMi0wLjA0LDAuNDE1LDAuMDEyLDAuNjYzQzIzLjIwNiwyNC4xMTgsMjQuOTU
xLDI0LjQxLDI1LjIwNCwyNS4wNDZ6Ii8+PHBhdGggZmlsbD0iI2ZhZmFmYSIgZD0iTTI5LjM3MiwyNS43MTNjMC4zNDQsMCwwLjQ1MS0wLjIzOCwwLjQ3NS0wLjM2YzAuMDEtMC4wNTQsMC4wMTMtMC4xMjUsMC4wMTItMC4xOVYyMS40OWgxLjI1NSB2My41NmMwLjAwMywwLjA5MS0wLjAwNiwwLjI3OS0wLjAxMSwwLjMyNWMtMC4wODgsMC45MjctMC44MjEsMS4yMjctMS43MzIsMS4yMjdjLTAuOTEzLDAtMS42NDYtMC4zMDEtMS43MzMtMS4yMjcgYy0wLjAwNC0wLjA0N
y0wLjAxMy0wLjIzNS0wLjAxMS0wLjMyNXYtMy41NmgxLjI1NHYzLjY3MmMwLDAuMDY0LDAuMDAyLDAuMTM3LDAuMDEyLDAuMTkgQzI4LjkyMSwyNS40NzMsMjkuMDI1LDI1LjcxMywyOS4zNzIsMjUuNzEzeiIvPjxwYXRoIGZpbGw9IiNmYWZhZmEiIGQ9Ik0zOS43MjUsMjUuNjZjMC4zNTksMCwwLjQ4NS0wLjIyNywwLjUwOC0wLjM1OWMwLjAwOS0wLjA1NywwLjAxMi0wLjEyNiwwLjAxMS0wLjE4OXYtMC43MiBoLTAuNTA5di0wLjcyNGgxLjc2VjI1Yy0wLjAwMSwwLjA
5My0wLjAwMywwLjE2Mi0wLjAxOCwwLjMyN2MtMC4wODIsMC45MDMtMC44NjYsMS4yMjUtMS43NDUsMS4yMjUgYy0wLjg4MSwwLTEuNjYzLTAuMzIyLTEuNzQ3LTEuMjI1Yy0wLjAxNC0wLjE2Ni0wLjAxNi0wLjIzNC0wLjAxOC0wLjMyN2wwLjAwMS0yLjA4OWMwLTAuMDg4LDAuMDExLTAuMjQ0LDAuMDIxLTAuMzI3IGMwLjExLTAuOTI4LDAuODYyLTEuMjI2LDEuNzQzLTEuMjI2YzAuODgsMCwxLjY1MSwwLjI5NywxLjc0MiwxLjIyNmMwLjAxNiwwLjE1OCwwLjAxMSwwL
jMyNywwLjAxMSwwLjMyN3YwLjE2NmgtMS4yNTF2LTAuMjc4IGMwLjAwMSwwLjAwMS0wLjAwMi0wLjExOC0wLjAxNi0wLjE4OWMtMC4wMjEtMC4xMS0wLjExNi0wLjM2Mi0wLjQ5NS0wLjM2MmMtMC4zNjIsMC0wLjQ2NywwLjIzOC0wLjQ5NCwwLjM2MiBjLTAuMDE1LDAuMDY1LTAuMDIxLDAuMTU0LTAuMDIxLDAuMjM0djIuMjdjLTAuMDAxLDAuMDYzLDAuMDAzLDAuMTMyLDAuMDEzLDAuMTg5QzM5LjI0MSwyNS40MzMsMzkuMzY2LDI1LjY2LDM5LjcyNSwyNS42NnoiLz48L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Samsung</friendlyname>
</Brand>
<Brand alias="Brand" id="12">
<name>Sony</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icon-sony.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmc6c3ZnIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiIHhtbG5zOnN2Zz0iaH
R0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjgwIDEyODAiIHZlcnNpb249IjEuMSIgaWQ9InN2ZzEiIHNvZGlwb2RpOmRvY25hbWU9Imljb24tc29ueS5zdmciIGlua3NjYXBlOnZlcnNpb249IjEuNC4zICgwZDE1Zjc1MDQyLCAyMDI1LTEyLTI1KSIgd2lkdGg9IjEyODAiIGhlaWdodD0iMTI4MCI+PHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2aWV3MSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9y
ZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgaW5rc2NhcGU6em9vbT0iMC42MzQxODYzOSIgaW5rc2NhcGU6Y3g9Ii00NjIuNzk3NjkiIGlua3NjYXBlOmN5PSIyMjUuNDg1NzYiIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMjU2MCIgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTM2MC
IgaW5rc2NhcGU6d2luZG93LXg9IjAiIGlua3NjYXBlOndpbmRvdy15PSIwIiBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJnNCIgc2hvd2d1aWRlcz0idHJ1ZSI+PHNvZGlwb2RpOmd1aWRlIHBvc2l0aW9uPSIxNzMuMzcxMDgsNjQxLjg5MDI0IiBvcmllbnRhdGlvbj0iMCwtMSIgaWQ9Imd1aWRlMSIgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIvPjwvc29kaXBvZGk6bmFtZWR2aWV3Pjxzdmc6ZGVmcyBpZD0iZGVmczEi
Lz48c3ZnOmcgaWQ9IkxheWVyXzIiPjxzdmc6ZyBpZD0iZzQiIGlua3NjYXBlOmxhYmVsPSJsb2dvIj48c3ZnOnBhdGggZD0ibSA0NTYuMDEyOSw3NTEuNzQ2ODcgYyAtNDYuNDEyNzksMCAtODkuNDIwNzksLTEzLjgyMzk5IC0xMTguMDkyNzksLTM5LjYwMzE5IGEgOTYuODk1OTg5LDk2Ljg5NTk4OSAwIDAgMSAtMzIuMTI3OTksLTczLjE5MDM5IDk4LjMyOTU4OCw5OC4zMjk1ODggMCAwIDEgMzIuMTI3OTksLTcyLjkzNDQgYyAyNi42MjQsLTI0LjE5MTk5IDczLjcyOC
wtMzkuNTUxOTkgMTE4LjA5Mjc5LC0zOS41NTE5OSA0OS4wNzUxOSwwIDg4LjM3MTE5LDEyLjM2NDggMTE4LjM5OTk5LDM5LjYwMzE5IGEgOTcuNDA3OTg5LDk3LjQwNzk4OSAwIDAgMSAzMS42OTI3OSw3Mi44ODMyIDEwMS41Mjk1OSwxMDEuNTI5NTkgMCAwIDEgLTMxLjY5Mjc5LDczLjE5MDM5IGMgLTI3Ljk4MDgsMjUuOTMyOCAtNzEuOTEwNCwzOS42MDMxOSAtMTE4LjM5OTk5LDM5LjYwMzE5IHYgLTI5LjY0NDc5IGMgMjQuNjAxNiwwIDQ3LjQzNjc5LC04LjQ5OTIg
NjMuMzg1NTksLTI0LjM3MTIgMTUuOTQ4OCwtMTUuODcyIDIzLjE5MzYsLTM1LjEyMzIgMjMuMTkzNiwtNTguODc5OTkgMCwtMjIuNjgxNiAtNy45NjE2LC00My44Nzg0IC0yMy4xOTM2LC01OC44OCAtMTUuNzQ0LC0xNS40ODc5OSAtMzkuMTE2NzksLTI0LjIxNzU5IC02My4zODU1OSwtMjQuMjE3NTkgLTI0LjI2ODgsMCAtNDcuNzQzOTksOC42NTI4IC02My40ODc5OSwyNC4yMTc1OSAtMTUuMTgwOCwxNS4wMjcyIC0yMy4wNCwzNi4zMDA4IC0yMy4wNCw1OC44OCBhID
gyLjM1NTE5LDgyLjM1NTE5IDAgMCAwIDIzLjA0LDU4Ljg3OTk5IGMgMTUuNzQ0LDE1LjY5MjggMzkuMDY1NTksMjQuMzcxMiA2My40ODc5OSwyNC4zNzEyIHogTSAxMTcuMTIwMTQsNTI2LjQ2NjkgYyAtMjQuODA2MzkyLDAgLTUyLjk5MTk4OSw0LjY1OTIgLTc2Ljc5OTk4NiwxNS4zNiBDIDE4LjA5OTM1NSw1NTEuNzU5NyAxLjU3NWUtNCw1NjcuNzA4NDkgMS41NzVlLTQsNTk0LjE1MzI5IGEgNTQuMjIwNzk0LDU0LjIyMDc5NCAwIDAgMCAxNC43MTk5OTg1LDM3LjI3
MzYgYyA2LjQyNTU5OSw1LjkzOTIgMTYuNzkzNTk5LDE2LjAyNTYgNDMuODc4Mzk2LDIxLjk2NDggMTIuMTA4Nzk4LDIuNTU5OTkgMzcuOTkwMzk1LDYuNjgxNTkgNjMuNzY5NTg4LDkuMzk1MTkgMjUuNzc5MiwyLjcxMzYgNTAuNzY0OCw1LjEyIDYxLjAwNDgsNy44NTkyIDguMTQwOCwyLjA3MzYgMjEuODM2NzksNC44ODk2IDIxLjgzNjc5LDIwLjI0OTYgMCwxNS4zNiAtMTQuNDEyNzksMTkuOTY4IC0xNi45MjE1OSwyMC45NjY0IC0yLjUwODgsMC45OTg0IC0xOS44MT
Q0LDguOTM0NCAtNTAuODkyOCw4LjkzNDQgYSAyMTYuNDIyMzcsMjE2LjQyMjM3IDAgMCAxIC02MC41OTUxOSwtMTAuNDE5MiBjIC0xMS41OTY3OTksLTQuMTQ3MiAtMjMuNzU2Nzk3LC05LjYgLTM1LjA5NzU5NiwtMjMuNDQ5NiBhIDQwLjI2ODc5NSw0MC4yNjg3OTUgMCAwIDEgLTcuMjk1OTk5LC0yMi4yMjA4IEggNi4yNDY1NTY3IHYgNzguODQ3OTkgSCAzNy41Mjk3NTQgdiAtMTAuNjc1MTkgYSA0LjQ1NDM5OTUsNC40NTQzOTk1IDAgMCAxIDYuNzU4NCwtMy44NCAy
NDYuNDI1NTcsMjQ2LjQyNTU3IDAgMCAwIDQ1Ljc3Mjc5NCwxNC43OTY3OSBjIDE2LjQzNTIwMiwzLjQzMDQgMjcuMDU5MTkyLDUuOTEzNiA0Ny40ODc5OTIsNS45MTM2IGEgMjAyLjYyMzk4LDIwMi42MjM5OCAwIDAgMCA2My42NDE2LC04Ljk4NTYgMTExLjA3ODM5LDExMS4wNzgzOSAwIDAgMCAzNy44MTExOSwtMTguNjYyMzkgNTEuODE0Mzk0LDUxLjgxNDM5NCAwIDAgMCAyMC4yNDk1OSwtNDEuNDk3NiA1OC4wNjA3OTMsNTguMDYwNzkzIDAgMCAwIC0xNi4zNTgzOS
wtNDAuODA2MzkgNzIuMDEyNzkyLDcyLjAxMjc5MiAwIDAgMCAtMjAuMTcyOCwtMTMuNzk4NCAxNDguNjA3OTgsMTQ4LjYwNzk4IDAgMCAwIC0yNC44ODMxOSwtOC42Nzg0IGMgLTE2LjIzMDQsLTMuOTY4IC01Mi42ODQ4LC04LjkzNDQgLTcwLjExODQsLTEwLjY3NTIgLTE4LjI3ODM5LC0xLjg5NDQgLTQ5Ljk5Njc5LC00LjUzMTIgLTYyLjY2ODc4OSwtOC40NDggLTMuODM5OTk5LC0xLjIwMzIgLTExLjY3MzU5OSwtNC45MTUyIC0xMS42NzM1OTksLTE0LjAwMzIgMCwt
Ni40NzY4IDMuNTg0LC0xMS45NTUyIDEwLjY0OTU5OSwtMTYuMzg0IEMgNzUuMjY0MTUsNTYwLjc3MDkgOTcuOTQ1NzQ3LDU1Ni4zOTMzIDEyMS42MDAxNCw1NTYuMzkzMyBhIDE2Ni45ODg3OCwxNjYuOTg4NzggMCAwIDEgNjYuNzEzNiwxMy4wMzAzOSA3Mi44NTc1OTEsNzIuODU3NTkxIDAgMCAxIDE1Ljg3MTk5LDkuNDcyIDQ3LjcxODM5NCw0Ny43MTgzOTQgMCAwIDEgMTUuNjQxNiwyNi4xNjMyIGggMjUuMjY3MiBWIDUzNi40MjUzIGggLTI4LjE2IHYgNy45NjE2IG
MgMCwyLjU2IC0yLjU2LDUuOTM5MiAtNy42OCwzLjE0ODggLTEyLjY5NzU5LC02LjYwNDggLTQ4LjM4Mzk5LC0yMC44ODk2IC05Mi4xMzQzOSwtMjEuMDY4OCB6IG0gNjE4LjIxNDMzLDEyLjU5NTIgMTM3LjYyNTU4LDEyNC4xODU1OCAtMS40MDgsLTgzLjYwOTU5IGMgLTAuMTUzNiwtMTAuOTgyNCAtMi4xNTA0LC0xNS41NjQ3OSAtMTQuMDI4OCwtMTUuNTY0NzkgaCAtMjUuODU1OTkgdiAtMjUuMDExMiBoIDExNy43NTk5OCB2IDI1LjAxMTIgaCAtMjUuMjY3MTkgYyAt
MTIuMDgzMiwwIC0xMi44LDMuODkxMTkgLTEzLjAwNDgsMTUuNTY0NzkgbCAyLjEyNDgsMTU5Ljc2OTU5IGggLTQwLjMyIEwgNzE0LjQxOTI3LDU5Ny45NDIwOSB2IDEwMC4zNzc1OSBjIDAuMTI4LDEwLjkzMTIgMC42NCwxNi4wNzY4IDExLjg3ODQsMTYuMDc2OCBoIDI4LjE2IHYgMjUuMDExMiBIIDYzOS4wMjcyOCB2IC0yNS4wMTEyIGggMjcuMDMzNiBjIDEwLjA4NjM5LDAgOS42NzY3OSwtOS42MjU2IDkuNjc2NzksLTE2LjY0IFYgNTgwLjU4NTI5IGMgMCwtNy42OC
AtMS4wNzUyLC0xNi40ODYzOSAtMTYuODk1OTksLTE2LjQ4NjM5IGggLTIxLjkxMzYgViA1MzkuMDYyMSBaIE0gMTA4My43NzYsNzE0LjM0NTI4IGEgNTUuODU5MTkzLDU1Ljg1OTE5MyAwIDAgMCA2Ljk2MzIsLTAuNDM1MiA4LjYyNzE5OSw4LjYyNzE5OSAwIDAgMCA1LjQyNzIsLTQuODEyOCAyOC4wMDYzOTcsMjguMDA2Mzk3IDAgMCAwIDAuNTM3NiwtNS40MDE2IHYgLTM5LjU1MiBjIDAsLTEuMzMxMiAwLC0xLjM1NjggLTEuNjg5NiwtMy40NTYgLTEuNjg5NiwtMi4w
OTkyIC03Mi4wODk2LC04MS45MTk5OSAtNzUuMjg5NiwtODUuNTAzOTkgLTMuOTkzNiwtNC4zNTIgLTExLjAwOCwtMTEuMDg0NzkgLTIxLjY4MzIsLTExLjA4NDc5IGggLTI0LjQ0Nzk2IHYgLTI1LjAzNjggaCAxMzcuOTgzOTYgdiAyNC45ODU2IGggLTE2LjY0IGMgLTMuODQsMCAtNi40LDMuNjYwNzkgLTMuMTIzMiw3LjY3OTk5IDAsMCA0Ni40Mzg0LDU1LjU1MiA0Ni44NzM2LDU2LjE0MDggMC40MzUyLDAuNTg4OCAwLjgxOTIsMC43MTY4IDEuNDA4LDAuMTc5MiAwLj
U4ODgsLTAuNTM3NiA0Ny41OTA0LC01NS44MDggNDcuOTQ4OCwtNTYuMzIgYSA0Ljc4NzE5OTQsNC43ODcxOTk0IDAgMCAwIC00LjA5NiwtNy42Nzk5OSBoIC0xNy4wNzUyIFYgNTM5LjA2MjEgSCAxMjgwIHYgMjUuMDM2OCBoIC0yNS4yNjcyIGMgLTkuMTY0OCwwIC0xMi44LDEuNjg5NTkgLTE5Ljc4ODgsOS40NzE5OSBsIC03Ni4xNiw4Ni44ODYzOSBhIDUuMzc1OTk5NCw1LjM3NTk5OTQgMCAwIDAgLTAuOTIxNiwzLjY4NjQgdiAzOS41MjY0IGEgMjguMTU5OTk3LDI4
LjE1OTk5NyAwIDAgMCAwLjU2MzIsNS40MDE2IDguNTI0Nzk5LDguNTI0Nzk5IDAgMCAwIDUuNDAxNiw0LjgxMjggNTAuNjExMTk0LDUwLjYxMTE5NCAwIDAgMCA2LjkxMiwwLjQzNTIgaCAyNS44MzA0IHYgMjUuMDM2OCBoIC0xMzcuMjY3MiB2IC0yNS4wMzY4IHoiIGlkPSJwYXRoMSIgZmlsbD0iIzAwMDAwMCIgc3R5bGU9InN0cm9rZS13aWR0aDoyLjU2Ii8+PC9zdmc6Zz48L3N2ZzpnPjwvc3ZnOnN2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Sony</friendlyname>
</Brand>
<Brand alias="Brand" id="13">
<name>Toshiba</name>
<logo><mimetype>image/svg+xml</mimetype><filename>logo-toshiba.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmc6c3ZnIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiIHhtbG5zOnN2Zz0
iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSI4MDAiIGhlaWdodD0iODAwIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA4MDAgODAwLjAxOTY5IiBpZD0ic3ZnMSIgc29kaXBvZGk6ZG9jbmFtZT0ibG9nby10b3NoaWJhLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS40LjMgKDBkMTVmNzUwNDIsIDIwMjUtMTItMjUpIj48c3ZnOmRlZnMgaWQ9ImRlZnMxIi8+PHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2a
WV3MSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9yZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgc2hvd2d1aWRlcz0idHJ1ZSIgaW5rc2NhcGU6em9vbT0iMS41MzgxMjUiIGlua3NjYXBlOmN4PSIzNzguNzA3ODQiIGlua3NjYXBlOmN5PSIyODg
uMDEzIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjI1NjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNjAiIGlua3NjYXBlOndpbmRvdy14PSIwIiBpbmtzY2FwZTp3aW5kb3cteT0iMCIgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMSI+PHNvZGlwb2RpOmd1aWRlIHBvc2l0aW9uPSIyMjcuMzE3MTYsMzk5LjM4NTQyIiBvcmllbnRhdGlvbj0iMCwtMSIgaWQ9Imd1aWRlMSIgaW5rc2NhcGU6bG9ja2VkPSJmY
WxzZSIvPjwvc29kaXBvZGk6bmFtZWR2aWV3PgogIDxzdmc6cGF0aCBmaWxsPSIjZTYxZTFlIiBkPSJtIDc2Ni4xMDAxNiw0NTkuNzEzNiBoIDM0LjU1IGwgLTM1LjY1LC0xMTcuNjYgLTQ5LjEsLTAuMDAyIC0zNS42NSwxMTcuNjYgaCAzNC41NiBsIDYuMywtMjEuNzggaCAzOC42NiBsIDYuMzMsMjEuNzggbSAtMzcuNTEsLTQ3Ljk0MyAxMS43NiwtNDAuNjUxIGggMC4yIGwgMTEuNzYsNDAuNjUxIHogbSAtNTU1LjQ2LDUwLjA1NSBjIDM1LjQ4LDAgNTIuNjMsLTYuMjU
gNTUuMDYsLTM4LjI2NSAwLjU4LC03LjYxOCAwLjY5LC0xNS40MzkgMC42OSwtMjIuNjg5IDAuMDEsLTcuMjI1IC0wLjExLC0xNS4wNTQgLTAuNjksLTIyLjY3MSAtMi40MywtMzIuMDI1IC0xOS41OCwtMzguMjY1IC01NS4wNiwtMzguMjY1IC0zNS40OCwwIC01Mi42Miw2LjI0IC01NS4wNCwzOC4yNjUgLTAuNTksNy42MTcgLTAuNzEsMTUuNDQ2IC0wLjcxLDIyLjY3MSAwLjAxLDcuMjUgMC4xMiwxNS4wNzEgMC43MSwyMi42ODkgMi40MiwzMi4wMTUgMTkuNTYsMzguMjY1IDU1LjA0LDM4LjI2NSBtIC0yMi4zMSwtNjAuOTU0IGMgMCwtNi40NjEgMC4xNiwtMTAuMjggMC4zLC0xMy4xMTQgMC45LC0xOC4xNjEgOC4wNywtMjAuMjc4IDIyLjAxLC0yMC4yNzggMTMuOTUsMCAyMS4xMiwyLjExNyAyMi4wMSwyMC4yNzggMC4xNCwyLjgzMyAwLjMxLDYuNjUyIDAuMzEsMTMuMTE0IDAsNi40ODIgLTAuMTcsMTAuMzA4IC0wLjMxLDEzLjEzNSAtMC44OSwxOC4xNjQgLTguMDYsMjAuMjg1IC0yMi4wMSwyMC4yODUgLTEzLjk0LDAgLTIxLjExLC0yLjEyMSAtMjIuMDEsLTIwLjI4NSAtMC4xNCwtMi44MjcgLTAuMywtNi42NTMgLTAuMywtMTMuMTM1IHogTSAwLjY1MDE1ODIyLDM0Mi4xMDU2IHYgMjkuMzMxIEggMzUuODIyMTU4IHYgODguMzI3IGggMzUuMTg1IHYgLTg4LjMyNyBoIDM1LjE3MzAwMiB2IC0yOS4zMzEgSCAwLjY1MDE1ODIyIE0gNTQwLjUwMDE2LDQ1OS43MTM2IHYgLTExNy42NjIgaCAtMzMuMzkgdiAxMTcuNjYyIGggMzMuMzkgbSAtMTM0LjM1LC03NC43MDMgdiAtNDIuOTU5IGggLTMzLjIgdiAxMTcuNjYyIGggMzMuMiB2IC00NS4zNzIgaCAzOC41OCB2IDQ1LjM3MiBoIDMzLjE5IHYgLTExNy42NjIgaCAtMzMuMTkgdiA0Mi45NTkgaCAtMzguNTggbSAyNDQuMTcsMTMuMjA2IGMgMTQuNzksLTMuNzgxIDE5LjEzLC0xMi42MTYgMTkuMTMsLTI1LjM4NiAwLC0yNS44NTkgLTE2LjI3LC0zMC43OCAtMzkuNCwtMzAuNzggaCAtNTkuOTUgdiAxMTcuNjYgaCA2Mi45MiBjIDI4Ljk3LDAgMzguNzEsLTEyLjQ4IDM4LjcxLC0zMS42NzUgMCwtMTMuMzgzIC0zLjA2LC0yNS4xOTEgLTIxLjQxLC0yOS44MjIgbSAtNDcuMDMsMTMuMTY5IGggMjMuMDIgYyA5LjMsMCAxMS4yNCw0LjA3NCAxMS4yNCwxMC43IDAsNi42MzIgLTMuNjQsMTAuNzE3IC0xMS4yNCwxMC43MTcgaCAtMjMuMDIgeiBtIDAsLTQyLjQyNSBoIDIzLjAyIGMgNi4wMSwwIDkuNzMsMi44NTEgOS43Myw5LjcwOCAwLDUuODc4IC0zLjY4LDkuNDk2IC05LjczLDkuNDk2IGggLTIzLjAyIHogbSAtMzU1LjA2LDUyLjE0MyBoIDMxLjY1IGMgMC4wMyw1LjcwOCAwLjc2LDkuNTIzIDMuNTMsMTEuNjMgMy4xNSwyLjM3NCA1Ljk3LDMuMTU4IDE1LjMyLDMuMTU4IDksMCAxOC44NiwwIDE4Ljg2LC0xMS4wODUgMCwtOC43NDIgLTUuNTEsLTEwLjczNyAtMTUuNjgsLTExLjI3OSAtMjUuMjIsLTEuMzM2IC0zNC4zNCwtMi4wNDkgLTQzLjczLC05LjAyNSAtNi40LC00Ljc1NyAtOS43MiwtMTQuMDE4IC05LjcyLC0yNi41NDIgMCwtMjEuMjk3IDcuNDMsLTI4Ljc2OCAxOC4xNSwtMzMuOTgxIDExLjA2LC01LjM4MSA1NC40NywtNS4zODEgNjYuMTUsMCAxNC42OSw2Ljc2OCAxNS4xMiwyMS40MiAxNS4xMiwzNS4wMTEgaCAtMzEuNTcgYyAtMC4wNiwtNi45MjkgLTEuNjIsLTguODg2IC0yLjg5LC0xMC4xNzUgLTMuMjgsLTIuOTA4IC03Ljk1LC0zLjUyMiAtMTQuNjksLTMuNTIyIC04LjE2LDAgLTE3LjYsMC4zNjggLTE3LjYsMTAuMjc3IDAsNy41NiAzLjI3LDEwLjcyIDExLjg1LDExLjI3NiAxMS43OSwwLjc1NCAzNS4wMiwxLjQ5NyA0My4zLDYuMzgzIDExLjYxLDYuODY3IDE0LjYyLDE2LjE1OSAxNC42MiwzMS4zMTkgMCwyMS45MDggLTcuODQsMjguMzM4IC0xOC43NSwzMy4xNTggLTEyLjU5LDUuNTYgLTU0LjY0LDUuNTYgLTY4LjMxLC0wLjQzIC0xNS4zLC02LjY3IC0xNS42MSwtMTkuOTY0IC0xNS42MSwtMzYuMTczIiBpZD0icGF0aDEiLz4KPC9zdmc6c3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>Brand</finalclass>
<friendlyname>Toshiba</friendlyname>
</Brand>
</Set>

View File

@@ -1,48 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<OSFamily alias="OSFamily" id="1">
<name>Arch</name>
<finalclass>OS Family</finalclass>
<friendlyname>Arch</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="2">
<name>Debian</name>
<finalclass>OS Family</finalclass>
<friendlyname>Debian</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="3">
<name>Oracle Linux</name>
<finalclass>OS Family</finalclass>
<friendlyname>Oracle Linux</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="4">
<name>Red Hat</name>
<finalclass>OS Family</finalclass>
<friendlyname>Red Hat</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="5">
<name>Ubuntu</name>
<finalclass>OS Family</finalclass>
<friendlyname>Ubuntu</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="6">
<name>Ubuntu server</name>
<finalclass>OS Family</finalclass>
<friendlyname>Ubuntu server</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="7">
<name>vCenter Server</name>
<finalclass>OS Family</finalclass>
<friendlyname>vCenter Server</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="8">
<name>Windows</name>
<finalclass>OS Family</finalclass>
<friendlyname>Windows</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="9">
<name>Windows server</name>
<finalclass>OS Family</finalclass>
<friendlyname>Windows server</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="1">
<name>Arch</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-arch-linux.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCwwLDI1NiwyNTYiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIGZpbGwtcnVsZT0ibm9uemVybyI+PGcgZmlsbD0iIzAwODhjYyIgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWRhc2hhcnJheT0iIiBzdHJva2UtZGFzaG9mZnNldD0iMCIgZm9udC1mYW1pbHk9Im5vbmUiIGZvbnQtd2VpZ2h0PSJub25lIiBmb250LXNpemU9Im5vbmUiIHRleHQtYW5jaG9yPSJub25lIiBzdHlsZT0ibWl4LWJsZW5kLW1vZGU6IG5vcm1hbCI+PGcgdHJhbnNmb3JtPSJzY2FsZSg1LjMzMzMzLDUuMzMzMzMpIj48cGF0aCBkPSJNMjguNDY1LDM4LjYxMWMwLjQxOSwtMS4xMDUgMC42NjQsLTIuMzY1IDAuNjY0LC0zLjcxNGMwLC00LjEzMyAtMi4yMTEsLTcuNDk0IC00LjkyOSwtNy40OTRjLTIuNzQxLDAgLTQuOTUxLDMuMzYxIC00Ljk1MSw3LjQ5NGMwLDEuMzI2IDAuMjIxLDIuNTg2IDAuNjQxLDMuNjY5Yy05LjA0MSwwLjk1MSAtMTUuNDA3LDQuNzMxIC0xNy45OTMsNi40MzJjNC4zNTUsLTYuMjc4IDguOTA5LC0xMy42MzggMTMuMjYyLC0yMi4xMDVjMS4wODMsLTIuMTAxIDIuMTAxLC00LjE3OCAzLjA1LC02LjIxMWMwLjM3NSwwLjI0MyAwLjc1MSwwLjUwOSAxLjE3MSwwLjc3NWMxLjk0NSwxLjIxNSAzLjc1OSwxLjg3OSA1LjA4NCwyLjIzM2MtMC45NzMsLTAuNzMgLTIuMDMzLC0xLjYxMyAtMy4xMTYsLTIuNjk3Yy0wLjgxNywtMC44MTcgLTEuNTQ3LC0xLjYzNyAtMi4xNjcsLTIuNDMzYzEuODM1LC00LjAyMiAzLjQyNywtNy44OTEgNC44MTksLTExLjU2YzIuMzIsNi4xNDQgNS4yMTcsMTIuODQyIDguODQxLDE5Ljg5M2MyLjM0Myw0LjUzMSA0LjczMSw4Ljc1NCA3LjExNywxMi42NDRjLTAuNjg1LC0wLjM3NSAtMS40MzcsLTAuNzMgLTIuMjMzLC0xLjAzOWMtMS4zNzEsLTAuNTMgLTIuNjUyLC0wLjg2MiAtMy43NTksLTEuMDZjMS41MDMsMC43NTEgMy4yNSwxLjc0NyA1LjA4NCwzLjA3M2MxLjE5NCwwLjg4NSAyLjI1NCwxLjc2OSAzLjE2MSwyLjYzMWMwLjAyMSwwLjAyMSAwLjAyMSwwLjAyMSAwLjA0NSwwLjA0NWMxLjI2LDIuMDU2IDIuNTY1LDMuOTU3IDMuODQ2LDUuODEzYy0yLjU0MSwtMS42ODEgLTguNzk2LC01LjM5NSAtMTcuNjM3LC02LjM4OXoiLz48L2c+PC9nPjwvc3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Arch</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="2">
<name>Debian</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-debian.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNFOTFFNjMiIGQ9Ik0yNi43NjMsMjQuNTQ4Yy0wLjYxNCwwLjAxLDAuMTE3LDAuMzE3LDAuOTE4LDAuNDRjMC4yMi0wLjE3MiwwLjQxOS0wLj
M0OCwwLjYtMC41MTVDMjcuNzgxLDI0LjU5MiwyNy4yNzQsMjQuNTk0LDI2Ljc2MywyNC41NDggTTMwLjA1NCwyMy43MjdjMC4zNjQtMC41LDAuNjMxLTEuMDU1LDAuNzIzLTEuNjI0Yy0wLjA4MiwwLjQwNS0wLjMwMywwLjc1NS0wLjUxLDEuMTI4Yy0xLjE0NiwwLjcyMS0wLjEwOC0wLjQzLDAtMC44NjVDMjkuMDM1LDIzLjkxMywzMC4wOTgsMjMuMjkzLDMwLjA1NCwyMy43MjcgTTMxLjI2OSwyMC41NjhjMC4wNzMtMS4xMDUtMC4yMTktMC43NTYtMC4zMTctMC4zMzZD
MzEuMDY4LDIwLjI5NCwzMS4xNTYsMjEuMDEzLDMxLjI2OSwyMC41NjggTTI0LjQzOSw1LjQ3OGMwLjMyNywwLjA1OCwwLjcwNiwwLjEwNCwwLjY1MywwLjE4M0MyNS40NDksNS41ODIsMjUuNTMxLDUuNTEsMjQuNDM5LDUuNDc4IE0yNS4wOTMsNS42NmwtMC4yMzIsMC4wNDdsMC4yMTUtMC4wMTdMMjUuMDkzLDUuNjYgTTM1LjI5NCwyMC45ODZjMC4wMzgsMC45OTEtMC4yOSwxLjQ3Mi0wLjU4NSwyLjMyMmwtMC41MjksMC4yNjZjLTAuNDM1LDAuODQxLDAuMDQxLDAuNT
M1LTAuMjY4LDEuMjAyYy0wLjY3OSwwLjYwMy0yLjA1NSwxLjg4My0yLjQ5NiwyLjAwNGMtMC4zMjEtMC4wMDksMC4yMTgtMC4zODIsMC4yODktMC41MjZjLTAuOTA2LDAuNjItMC43MjgsMC45MzQtMi4xMTMsMS4zMTNsLTAuMDQxLTAuMDljLTMuNDE5LDEuNjA3LTguMTY2LTEuNTc2LTguMTAzLTUuOTI4Yy0wLjAzNywwLjI3NS0wLjEwNCwwLjIwOS0wLjE4LDAuMzJjLTAuMTc1LTIuMjM3LDEuMDMzLTQuNDg2LDMuMDczLTUuNDAzYzEuOTk1LTAuOTg3LDQuMzM1LTAu
NTgsNS43NjMsMC43NWMtMC43ODUtMS4wMjgtMi4zNDgtMi4xMTktNC4xOTktMi4wMTdjLTEuODE0LDAuMDI5LTMuNTEsMS4xODItNC4wNzcsMi40MzRjLTAuOTI5LDAuNTg1LTEuMDM4LDIuMjU2LTEuNDQxLDIuNTYzYy0wLjU0NSw0LjAwMywxLjAyNCw1LjczMywzLjY4LDcuNzY4YzAuNDE3LDAuMjgyLDAuMTE4LDAuMzI2LDAuMTc1LDAuNTQxYy0wLjg4My0wLjQxMi0xLjY5LTEuMDM3LTIuMzU0LTEuODAxYzAuMzUzLDAuNTE3LDAuNzMzLDEuMDE3LDEuMjIzLDEuND
FjLTAuODMxLTAuMjc5LTEuOTQyLTIuMDEzLTIuMjY3LTIuMDg0YzEuNDM1LDIuNTY3LDUuODE4LDQuNTAyLDguMTEzLDMuNTQxYy0xLjA2MiwwLjA0LTIuNDEyLDAuMDIxLTMuNjA0LTAuNDJjLTAuNTAxLTAuMjU3LTEuMTgzLTAuNzkxLTEuMDYyLTAuODkzYzMuMTMzLDEuMTcxLDYuMzY5LDAuODg3LDkuMDc4LTEuMjg2YzAuNjg5LTAuNTM3LDEuNDQzLTEuNDQ5LDEuNjYyLTEuNDY0Yy0wLjMyNywwLjQ5MywwLjA1NywwLjIzOS0wLjE5NywwLjY3NGMwLjY4OC0xLjEw
OS0wLjI5OS0wLjQ0OSwwLjcxMS0xLjkxM2wwLjM3MywwLjUxMmMtMC4xMzktMC45MTcsMS4xNDMtMi4wMzMsMS4wMTItMy40ODljMC4yOTEtMC40NDUsMC4zMjYsMC40NzgsMC4wMTUsMS41MDJjMC40MzQtMS4xMzYsMC4xMTMtMS4zMTcsMC4yMjQtMi4yNTRjMC4xMjEsMC4zMTUsMC4yNzksMC42NDgsMC4zNTksMC45ODFjLTAuMjgxLTEuMDk3LDAuMjg5LTEuODQ4LDAuNDMzLTIuNDg1Yy0wLjE0Mi0wLjA2My0wLjQzNSwwLjQ4NS0wLjUwMy0wLjgxMmMwLjAxLTAuNT
YyLDAuMTU2LTAuMjk1LDAuMjE0LTAuNDM1Yy0wLjExMS0wLjA2NC0wLjQtMC40OTYtMC41NzctMS4zMjNjMC4xMjctMC4xOTMsMC4zNDIsMC41MDYsMC41MTYsMC41MzNjLTAuMTEyLTAuNjU1LTAuMzA0LTEuMTU5LTAuMzEzLTEuNjY1Yy0wLjUxLTEuMDYxLTAuMTgxLDAuMTQzLTAuNTkyLTAuNDU4Yy0wLjU0My0xLjY4NywwLjQ0OS0wLjM5LDAuNTE0LTEuMTU2YzAuODIsMS4xODgsMS4yODksMy4wMjksMS41MDQsMy43OTJjLTAuMTY0LTAuOTMtMC40MjgtMS44MzIt
MC43NTItMi43MDRjMC4yNDksMC4xMDgtMC40MDEtMS45MTEsMC4zMjQtMC41NzVjLTAuNzcyLTIuODQ4LTMuMzE0LTUuNTExLTUuNjUtNi43NmMwLjI4NiwwLjI2MiwwLjY0NiwwLjU5MSwwLjUxNywwLjY0MmMtMS4xNjMtMC42OS0wLjk1OS0wLjc0NS0xLjEyNC0xLjA0MWMtMC45NDYtMC4zODMtMS4wMSwwLjAzNC0xLjYzNiwwYy0xLjc4Ni0wLjk0My0yLjEyOS0wLjg0NS0zLjc3Mi0xLjQzN2wwLjA3OCwwLjM0OWMtMS4xODQtMC4zOTQtMS4zNzksMC4xNDYtMi42NT
csMC4wMDJjLTAuMDc4LTAuMDYyLDAuNDEtMC4yMTksMC44MTEtMC4yNzhjLTEuMTQzLDAuMTUtMS4wOS0wLjIyOC0yLjIwOCwwLjA0MmMwLjI3Ny0wLjE5NywwLjU2Ni0wLjMyMiwwLjg2MS0wLjQ4NmMtMC45MzIsMC4wNTktMi4yMjYsMC41NDItMS44MjUsMC4xMDNjLTEuNTIxLDAuNjc2LTQuMjIsMS42My01LjczNSwzLjA1MWwtMC4wNDctMC4zMjJjLTAuNjk0LDAuODM1LTMuMDI4LDIuNDkyLTMuMjE1LDMuNTdsLTAuMTg1LDAuMDQzYy0wLjM2MSwwLjYxMy0wLjU5
NSwxLjMwNS0wLjg4MSwxLjkzNWMtMC40NzQsMC44MDYtMC42OTIsMC4zMTEtMC42MjYsMC40MzZjLTAuOTI5LDEuODgzLTEuMzksMy40NjctMS43OSw0Ljc2OGMwLjI4NCwwLjQyNCwwLjAwNywyLjU1OCwwLjExMyw0LjI2NGMtMC40NjcsOC40MjksNS45MTYsMTYuNjA5LDEyLjg5MSwxOC41YzEuMDIzLDAuMzY1LDIuNTQyLDAuMzU0LDMuODM2LDAuMzljLTEuNTI1LTAuNDM4LTEuNzIyLTAuMjMyLTMuMjA5LTAuNzQ5Yy0xLjA3NC0wLjUwNi0xLjMwOC0xLjA4Mi0yLj
A2Ni0xLjc0bDAuMywwLjUzYy0xLjQ5LTAuNTI2LTAuODY3LTAuNjUyLTIuMDc4LTEuMDM0bDAuMzIxLTAuNDI0Yy0wLjQ4Mi0wLjAzMi0xLjI3OS0wLjgxMS0xLjQ5Ny0xLjI0MWwtMC41MjgsMC4wMjFjLTAuNjM0LTAuNzgzLTAuOTcyLTEuMzQ4LTAuOTQ4LTEuNzg1bC0wLjE3LDAuMzA1Yy0wLjE5NC0wLjMzMi0yLjMzNS0yLjkzNy0xLjIyNC0yLjMzYy0wLjIwNy0wLjE4OC0wLjQ4MS0wLjMwNy0wLjc3OS0wLjg1bDAuMjI3LTAuMjU4Yy0wLjUzNS0wLjY4Ni0wLjk4
My0xLjU2OC0wLjk0OS0xLjg2YzAuMjg0LDAuMzg0LDAuNDgyLDAuNDU0LDAuNjc5LDAuNTIyYy0xLjM1MS0zLjM0OS0xLjQyNi0wLjE4Ny0yLjQ0OC0zLjQwOWwwLjIxNi0wLjAxOWMtMC4xNjYtMC4yNDYtMC4yNjUtMC41MjEtMC4zOTktMC43ODVsMC4wOTQtMC45MzhjLTAuOTcyLTEuMTI1LTAuMjcyLTQuNzgxLTAuMTMyLTYuNzgzYzAuMDk3LTAuODE2LDAuODExLTEuNjg0LDEuMzU0LTMuMDQ1bC0wLjMzMi0wLjA1NWMwLjYzMi0xLjEwNCwzLjYxMi00LjQzMyw0Lj
k5LTQuMjZjMC42NjktMC44NDEtMC4xMzItMC4wMDItMC4yNjMtMC4yMTVjMS40NjktMS41MiwxLjkzLTEuMDczLDIuOTItMS4zNDljMS4wNjgtMC42MzMtMC45MTcsMC4yNTEtMC40MS0wLjIzOWMxLjg0OC0wLjQ3MywxLjMxLTEuMDczLDMuNzE4LTEuMzExYzAuMjU0LDAuMTQ1LTAuNTksMC4yMjMtMC44LDAuNDFjMS41MzgtMC43NTMsNC44Ny0wLjU4NCw3LjAzNCwwLjQxN2MyLjUxMSwxLjE3Myw1LjMzLDQuNjQyLDUuNDQzLDcuOTA0bDAuMTI2LDAuMDM1Yy0wLjA2
MywxLjI5OCwwLjE5OCwyLjc5OC0wLjI1Nyw0LjE3NUwzNS4yOTQsMjAuOTg2IE0yMC4wNzIsMjUuMzg5bC0wLjA4NiwwLjQzMWMwLjQwMywwLjU0NywwLjcyNCwxLjE0MiwxLjIzNywxLjU2N0MyMC44NTMsMjYuNjY0LDIwLjU3NywyNi4zNjQsMjAuMDcyLDI1LjM4OSBNMjEuMDIzLDI1LjM1M2MtMC4yMTMtMC4yMzctMC4zNC0wLjUxOC0wLjQ4LTAuODAyYzAuMTM1LDAuNDk1LDAuNDExLDAuOTIyLDAuNjY5LDEuMzU3TDIxLjAyMywyNS4zNTMgTTM3Ljg3NywyMS42OD
hsLTAuMDg4LDAuMjI2Yy0wLjE2NiwxLjE3NC0wLjUyMywyLjMzMi0xLjA2OCwzLjQxMkMzNy4zMjQsMjQuMTg5LDM3LjcxNCwyMi45NDcsMzcuODc3LDIxLjY4OCBNMjQuNTYsNS4xODVDMjQuOTc0LDUuMDMxLDI1LjU3OSw1LjEwMSwyNi4wMTksNWMtMC41NzMsMC4wNDgtMS4xNDQsMC4wNzktMS43MDYsMC4xNTFMMjQuNTYsNS4xODUgTTEwLjAwNywxMi45MjNjMC4wOTUsMC44ODItMC42NjcsMS4yMjksMC4xNjcsMC42NDRDMTAuNjIzLDEyLjU2MiwxMCwxMy4yODYsMTAuMDA3LDEyLjkyMyBNOS4wMjgsMTcuMDE2YzAuMTkxLTAuNTkyLDAuMjI2LTAuOTQzLDAuMy0xLjI4NUM4Ljc5NywxNi40MSw5LjA4NCwxNi41NTMsOS4wMjgsMTcuMDE2Ii8+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Debian</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="3">
<name>Oracle Linux</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icon-oracle-linux.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dH
A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjMxIDIzMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pbllNaWQiIHZlcnNpb249IjEuMSIgaWQ9InN2ZzQiIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIyMzEiIGhlaWdodD0iMjMxIiBzb2RpcG9kaTpkb2NuYW1lPSJpY29uLW9yYWNsZS1saW51eC5zdmciIGlua3NjYXBlOnZlcnNpb249IjEuNC4zICgwZDE1Zjc1MDQyLCAy
MDI1LTEyLTI1KSI+PHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2aWV3MSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzAwMDAwMCIgYm9yZGVyb3BhY2l0eT0iMC4yNSIgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIgc2hvd2d1aWRlcz0idHJ1ZSIgaW5rc2NhcGU6em9vbT0iNy41MzMyOD
kxIiBpbmtzY2FwZTpjeD0iMTA3LjA1ODE1IiBpbmtzY2FwZTpjeT0iOTAuNzk2OTkzIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjI1NjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEzNjAiIGlua3NjYXBlOndpbmRvdy14PSIwIiBpbmtzY2FwZTp3aW5kb3cteT0iMCIgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnNCI+PHNvZGlwb2RpOmd1aWRlIHBvc2l0aW9uPSI0MS43NjM1ODksMTE1LjQ2OCIgb3JpZW50
YXRpb249IjAsLTEiIGlkPSJndWlkZTEiIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiLz48L3NvZGlwb2RpOm5hbWVkdmlldz48ZGVmcyBpZD0iZGVmczgiPjxyZWN0IHg9Ii0xMzguMjQ2NDEiIHk9IjgxLjU2NzIzOCIgd2lkdGg9IjM4Mi4zNjc0IiBoZWlnaHQ9IjI0MC4yMTE1NiIgaWQ9InJlY3Q0OTUiLz48cmVjdCB4PSItMTcuNjEyNjIzIiB5PSIxMDQuMzU4OTgiIHdpZHRoPSIxNzEuMDUyMzgiIGhlaWdodD0iMTk3LjMxNDQ0IiBpZD0icmVjdDI5MSIvPjwvZGVmcz
48ZyBpZD0iZzE0MDciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuNjEzMjE1NDIsNzYuODM1NTMzKSI+PHBhdGggZD0ibSA5OS41OSwxOS41MiBoIDE1LjI0IEwgMTA2Ljc4LDYuNTIgOTEuOTgsMzAgaCAtNi43MyBsIDE4LC0yOC4xNyBhIDQuMjksNC4yOSAwIDAgMSA3LC0wLjA1IEwgMTI4LjMsMzAgaCAtNi43MyBsIC0zLjE3LC01LjI1IGggLTE1LjQyIGwgLTMuMzYsLTUuMjMgbSA2OS45Myw1LjIzIFYgMC4yOCBoIC01LjcyIHYgMjYuODggYSAyLjc2LDIuNzYgMCAw
IDAgMC44NSwyIDIuODksMi44OSAwIDAgMCAyLjA4LDAuODcgaCAyNiBsIDMuMzksLTUuMjUgaCAtMjYuNjMgbSAtOTQuNTQsLTQuNCBhIDEwLjA1LDEwLjA1IDAgMCAwIDAsLTIwLjEgaCAtMjUgViAzMCBoIDUuNzEgViA1LjU0IGggMTguOTQgYSA0LjgxLDQuODEgMCAwIDEgMCw5LjYyIEggNTguNTIgTCA3NS41OCwzMCBoIDguMjkgTCA3Mi40MSwyMC4zOCBoIDIuNTcgTSAxNC44NiwzMCBoIDE3LjI3IGEgMTQuODYsMTQuODYgMCAwIDAgMCwtMjkuNzEgSCAxNC44Ni
BhIDE0Ljg2LDE0Ljg2IDAgMSAwIDAsMjkuNzEgbSAxNi44OCwtNS4yMyBoIC0xNi41IGEgOS42Miw5LjYyIDAgMCAxIDAsLTE5LjIzIGggMTYuNSBhIDkuNjIsOS42MiAwIDEgMSAwLDE5LjIzIE0gMTQwLjIzLDMwIGggMTcuNjMgbCAzLjM0LC01LjIzIGggLTIwLjU4IGEgOS42Miw5LjYyIDAgMSAxIDAsLTE5LjIzIGggMTYuNzUgbCAzLjM4LC01LjI1IGggLTIwLjUyIGEgMTQuODYsMTQuODYgMCAxIDAgMCwyOS43MSBtIDY5Ljg3LC01LjIzIGEgOS42Miw5LjYyIDAg
MCAxIC05LjI2LC03IGggMjQuNDIgbCAzLjM2LC01LjI0IGggLTI3Ljc4IGEgOS42MSw5LjYxIDAgMCAxIDkuMjYsLTcgaCAxNi43NiBsIDMuMzUsLTUuMjUgaCAtMjAuNSBhIDE0Ljg2LDE0Ljg2IDAgMCAwIDAsMjkuNzEgaCAxNy42MyBsIDMuMzUsLTUuMjMgaCAtMjAuNiIgc3R5bGU9ImZpbGw6I2M3NDYzNCIgaWQ9InBhdGgyIi8+PHBhdGggaWQ9InJlY3Q3NDkiIHN0eWxlPSJmaWxsOiNjNzQ2MzQ7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjUuMjUxOTtzdH
Jva2UtbGluZWNhcDpzcXVhcmU7cGFpbnQtb3JkZXI6c3Ryb2tlIGZpbGwgbWFya2VycyIgZD0ibSAyNS4zOTE1MTcsNDcuOTMwODcxIGggNC45ODA4NjMgdiAzLjgzMDAyNSBoIC00Ljk4MDg2MyB6IG0gNjEuNTAwOCwxOC41NTcwNjEgLTcuMjQsLTEwLjI0MDAwMiBoIDQuOTYgbCA0LjY0LDcuMDgwMDAyIGggMC4yNCBsIDQuNzYsLTcuMDgwMDAyIGggNC43MiBsIC03LjI4LDEwLjE2MDAwMiA3LjY0LDEwLjg4IGggLTQuOTYgbCAtNS4wOCwtNy43MiBoIC0wLjI0IGwg
LTUuMTIsNy43MiBoIC00LjcyIHogbSAtMjEuNTk5OTk4LDExLjI4IHEgLTYuNjgsMCAtNi42OCwtNy4yNCBWIDU2LjI0NzkzIGggNC4xMiB2IDEzLjc2MDAwMiBxIDAsMi4zNiAxLjA0LDMuMzIgMS4wOCwwLjkyIDMuMTIsMC45MiAxLjQsMCAyLjYsLTAuNjggMS4yLC0wLjcyIDEuODgsLTIgMC43MiwtMS4yOCAwLjcyLC0yLjk2IFYgNTYuMjQ3OTMgaCA0LjEyIHYgMjEuMDQwMDAyIGggLTMuMzIgbCAtMC40LC0yLjggaCAtMC4yOCBxIC0xLjE2LDEuNiAtMi45MiwyLj
Q0IC0xLjc2LDAuODQgLTQsMC44NCB6IE0gMzUuODEyMzIsNTYuMjQ3OTMgaCAzLjMyMDAwMSBsIDAuNCwyLjgwMDAwMiBoIDAuMjggcSAxLjEyLC0xLjYwMDAwMiAyLjg4LC0yLjQ0MDAwMiAxLjgsLTAuODQgNC4wNCwtMC44NCA2LjY4LDAgNi42OCw3LjI0MDAwMiB2IDE0LjI4IGggLTQuMTIgdiAtMTMuNzYgcSAwLC0yLjM2IC0xLjA4LC0zLjI4IC0xLjA0LC0wLjk2IC0zLjA4LC0wLjk2IC0xLjQsMCAtMi42LDAuNzIgLTEuMiwwLjY4IC0xLjkyLDEuOTYgLTAuNjgsMS4yOCAtMC42OCwyLjk2IHYgMTIuMzYgSCAzNS44MTIzMiBaIE0gMy42MTIzOSw0Ny45MzA4NzEgaCA0LjQ0IHYgMjUuNTE3MDYxIGggMTQuMjggdiAzLjg0IGggLTE4LjcyIHogTSAyNi4yNTY3NjgsNTkuNDYzOTUgViA3Ny4yODc5MzIgSCAzMC4zNzIzOCBWIDU2LjI3NTQ2NCBoIC02LjM4NzYxMiB2IDEuODI1NjgxIHoiLz48L2c+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Oracle Linux</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="4">
<name>Red Hat</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-red-hat.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMzNzQ3NEYiIGQ9Ik0yNy44MTMsMzQuODg4Yy0wLjMxOSwwLjM1My0wLjc1NSwwLjM3OC0xLjI4NCwwLjA3NWMtMC40OTctMC4yODItMS4yN
zYtMC4yODItMS41MS0wLjAwMSBjLTAuMjY5LDAuMzIzLTAuMDc1LDAuNjgxLDAuMzY3LDAuNjgxYzAuMjA3LDAsMC42MDQsMC4xMzcsMC44NzQsMC4zMDNjMC4yNzEsMC4xNjcsMC42NTMsMC4zMDMsMC44NDcsMC4zMDMgYzAuNDc1LDAuMDAyLDEuMjM0LTAuNzgyLDEuMjM0LTEuMjczQzI4LjM0MiwzNC41MDYsMjguMTgyLDM0LjQ4LDI3LjgxMywzNC44ODh6IE00MywyNS45NzFjMCwzLjIyMS0wLjUzNSw1LjYwMi0xLjg4Nyw4LjM4NiBjLTAuOTgsMi4wMjItMC44NDY
sMS45Mi0yLjI3MiwxLjc0Yy0xLjI5My0wLjE2My0yLjk4OS0wLjAyNi00LjA3NSwwLjMzMWMtMC40ODQsMC4xNi0wLjYxNywwLjI4My0wLjY4MSwwLjY0MyBjLTAuMDY1LDAuMzc5LTAuMjA2LDAuNDkzLTAuOTc5LDAuNzkzYy0wLjY1MiwwLjI1My0wLjk3NywxLjAzMy0xLjY4NiwxLjcyOGMtMC41NDMsMC41My0xLjEyMSwxLjAzLTEuMjg4LDEuMTEzIEMyOS43NDIsNDAuODk0LDI5LDQxLjA2OSwyOSw0MC45NzRjMC0wLjA3MSwwLjk4Ni0yLjI1MSwyLjM1Ny00LjIxO
GMwLjQ5LTAuNzA0LDAuNjYxLTEuMTA0LDAuNzA5LTEuNjYxIGMwLjAzNi0wLjQwNSwwLjIxMS0xLjIyOSwwLjM4OS0xLjgzYzAuMTc5LTAuNjAzLDAuMjg5LTEuMTMsMC4yNDYtMS4xNzNzLTAuMzcsMC4wMjUtMC43MjYsMC4xNDggYy0wLjc3OSwwLjI3NS0xLjI5MywwLjI4Ni0yLjE3NywwLjA1MWMtMC41NjMtMC4xNTEtMC43NzEtMC4xMzktMS4zNDQsMC4wOGMtMC42MzksMC4yNDYtMC43MTksMC4yNDYtMS4zMTMsMC4wMDYgYy0wLjU5NS0wLjIzNy0wLjcyNS0wLjI
zNy0yLjE0NiwwLjAxNGMtMi42NTUsMC40NjYtMy41MTMsMC4yMDYtNS4yODQtMS42MDljLTEuMDk4LTEuMTI1LTEuNTA4LTEuMzcyLTEuNzE3LTEuMDMgYy0wLjA1MSwwLjA4My0wLjI1MywwLjE1MS0wLjQ0NiwwLjE1MWMtMC4yNTgsMC0wLjQ4NC0wLjIwMy0wLjg0MS0wLjc2Yy0wLjI2Ny0wLjQxNS0wLjY3Ny0wLjg5My0wLjkwOS0xLjA1OCBjLTEuMjc0LTAuOTA2LTIuNzE1LTAuMjUtMi43MTUsMS4yNGMwLDAuNjE0LDEuMjI4LDIuNDY1LDEuODQ3LDIuNzg2YzAuO
DE4LDAuNDIzLDAuMzU3LDEuMDU3LTAuNjcxLDAuOTE5IGMtMC41MzItMC4wNzItMC43NjctMC4yMzEtMS40ODItMS4wMDNjLTAuNzY0LTAuODI2LTAuOTA3LTAuOTE2LTEuNDQzLTAuOTE0Yy0wLjMyOCwwLjAwMi0wLjg3NSwwLjEzMS0xLjIxNSwwLjI4NCBjLTAuODc3LDAuMzk5LTIuMDIyLDAuNjItMy4yMjEsMC42Mkg1Ljg2NUw1LjYzLDMxLjE0NkM1LjA5MywyOS4xNzEsNSwyOC40LDUsMjUuOTcxYzAtMS44NTcsMC4wNzEtMi44MjEsMC4yNzktMy43NzkgYzEuMTI
0LTUuMTcyLDMuOTg0LTkuMzUzLDguMzIzLTEyLjE2OWMyLjEyOC0xLjM4Miw0LjA4NC0yLjE5Miw2LjU3OS0yLjcyOWMxLjc4My0wLjM4Myw1Ljc3Ni0wLjM5NCw3LjUxLTAuMDIxIGM1LjkwMiwxLjI3MywxMC43OTQsNC45OTYsMTMuMzM5LDEwLjE2QzQyLjQ1NywyMC4zMjUsNDMsMjIuNjc3LDQzLDI1Ljk3MXoiLz48cGF0aCBmaWxsPSIjRkYzRDAwIiBkPSJNMzguMDgyLDIyLjMxMmMtMC43MTEtMC41MzktMi41MjktMS4zMjctMy4wNjMtMS4zMjdjLTAuMTQ2LDAtM
C40LDAuMjczLTAuNTk4LDAuNjQzIGMtMC4yOTcsMC41NTktMS4xMzEsMS4zMjItMS40NDQsMS4zMjJjLTAuMDU4LDAsMC4xMDEtMC4zODQsMC4zNS0wLjg1MmMwLjExLTAuMjA1LDAuMjA0LTAuNDIzLDAuMjgtMC42MzEgYzAuMTA5LTAuMzAzLDAuMTc4LTAuNTg0LDAuMTc4LTAuNzc2YzAtMC45NTgtMC42NzYtMy4xMTctMS40OTctNS4wNDljLTAuNDM1LTEuMDI0LTAuOTExLTEuOTg1LTEuMzUxLTIuNjY5IGMtMC4yMTUtMC4zMzUtMC4zOTMtMC41ODktMC41NTktMC4
3OTJjLTAuMjktMC4zNTEtMC41NTktMC41NTQtMC45NzUtMC43NzljLTAuMjgzLTAuMTUyLTAuNTgtMC4yNy0wLjg5MS0wLjM1NiBjLTAuMDA2LDAtMC4wMTItMC4wMDMtMC4wMTYtMC4wMDNjLTAuMDczLTAuMDIxLTAuMTQ1LTAuMDM5LTAuMjE5LTAuMDU1Yy0wLjAxMi0wLjAwMy0wLjAyMy0wLjAwNS0wLjAzNS0wLjAwOSBjLTAuMDctMC4wMTQtMC4xMzktMC4wMjYtMC4yMTItMC4wMzljLTAuMDE1LTAuMDAzLTAuMDI4LTAuMDAzLTAuMDQ0LTAuMDA2Yy0wLjA3Mi0wL
jAxMi0wLjE0Mi0wLjAyMS0wLjIxNS0wLjAzIGMtMC4wMTItMC4wMDEtMC4wMjUtMC4wMDEtMC4wMzctMC4wMDNjLTAuMTYtMC4wMTYtMC4zMjUtMC4wMjctMC40OTUtMC4wMjdjLTAuMDE3LDAtMC4wMzYsMC0wLjA1MywwIGMtMC4xMiwwLTAuMjM5LDAuMDA2LTAuMzYyLDAuMDE0Yy0wLjAzOSwwLjAwMS0wLjA3NiwwLjAwNC0wLjExNCwwLjAwNWMtMC4xMzIsMC4wMTEtMC4yNjcsMC4wMjQtMC40MDIsMC4wNDIgYy0wLjA0OCwwLjAwNi0wLjA5NSwwLjAxMy0wLjE0NCw
wLjAxOWMtMC4xMzQsMC4wMTktMC4yNywwLjA0MS0wLjQwOCwwLjA2OGMtMC4wNTUsMC4wMS0wLjExMiwwLjAyNC0wLjE3LDAuMDM2IGMtMC4xMDYsMC4wMjItMC4yMTgsMC4wNDgtMC4zMjksMC4wNzVjLTAuMDQzLDAuMDEtMC4wODMsMC4wMTctMC4xMjYsMC4wMjdjLTEuMDYzLDAuMjcyLTEuNTU4LDAuMzE5LTIuNTY2LDAuMjQ1IGMtNC4xMTctMC4yOTctMy45NTEtMC4zLTQuNjMsMC4wNDdjLTAuMzY4LDAuMTg4LTAuNjI4LDAuMzktMC44NDgsMC43M2MtMC4yOTgsM
C40NjItMC41MiwxLjE3Mi0wLjgyOSwyLjQ1MSBjLTAuNTgyLDIuNDAzLTAuNTk1LDMuMTQ2LTAuMDY4LDMuNzczYzAuNTM2LDAuNjM5LDIuMjY1LDEuNDMxLDMuOTksMS44MjdjMi4wNjMsMC40NzQsMy40NjksMC44OTIsMy44NTksMS4xNDkgYzAuMDk3LDAuMDYzLDAuMjA1LDAuMTc4LDAuMzAxLDAuMzEzYzAuMDkxLDAuMTI1LDAuMTcsMC4yNjYsMC4yMTgsMC4zOTRjMC40MzQsMS4xNTcsMC42NjcsMS42MjcsMC45MzEsMS44NjQgYzAuMDY1LDAuMDYsMC4xMjUsMC4
xMzEsMC4xNzQsMC4xOTdjMC4wNjYsMC4wOTIsMC4xMDcsMC4xODMsMC4xMDcsMC4yMzljMCwxLjA5Ny03LjgwMy0xLjMzMy05LjgxNC0zLjA1NCBjLTAuNTM4LTAuNDYyLTAuODM3LTAuODQ2LTAuOTY1LTEuMjg4Yy0wLjA3Ny0wLjI3NC0wLjA4Ny0wLjU3MS0wLjA0Ni0wLjkyMmwwLjAyNC0wLjIxMWwwLjA2My0wLjUzNGgtMC4wMDF2LTAuMDAybC0xLjk5OCwwLjA2NiBjLTEuNjg4LDAuMDU2LTIuMTA5LDAuMTE4LTIuNzE1LDAuNDEyYy0yLjA4NiwxLjAwNS0xLjk4N
SwyLjY5LDAuMjg4LDQuODVjMS42MzQsMS41NTQsNC4xMTMsMy4wODUsNi44NTMsNC4zMzQgYzIuODI4LDEuMjkzLDUuOTM2LDIuMjgzLDguNjgxLDIuNjg2YzEuMTg4LDAuMTc1LDIuNzEyLDAuMjM3LDQuMTEzLDAuMTkzYzAuNzkxLTAuMDI0LDEuNTQzLTAuMDg0LDIuMTctMC4xOCBjMy4zNjUtMC41MTMsNS42OTUtMS44ODYsNi42NjgtMy45MzRjMC4xMDUtMC4yMjIsMC4xODktMC40MzgsMC4yNTgtMC42NTJDMzkuODE4LDI0LjY1NCwzOS4zNzcsMjMuMjk3LDM4LjA
4MiwyMi4zMTJ6IE0yMi4xMjIsMTYuMDE1Yy0xLjQzOCwwLjE1OS0yLjE0MSwwLjM1NS0yLjQwMywwLjY3MWMtMC4xMDEsMC4xMjEtMC4yMDQsMC4xODgtMC4zMjcsMC4xOTdjLTAuMjQ5LDAuMDE3LTAuNTctMC4yMTUtMS4wODktMC43NDIgYy0wLjM2MS0wLjM3MS0wLjU2Ny0wLjYzNy0wLjY2Ny0wLjg2N2MtMC4wNS0wLjExNS0wLjA3My0wLjIyNi0wLjA3My0wLjMzMmMwLTAuMDYxLDAuMDA0LTAuMTIsMC4wMS0wLjE3OCBjMC4wMDEtMC4wMDgsMC4wMDMtMC4wMTYsM
C4wMDMtMC4wMjNjMC4wMDctMC4wNDcsMC4wMTYtMC4wOTMsMC4wMjgtMC4xMzljMC4wMDEtMC4wMDksMC4wMDMtMC4wMTUsMC4wMDUtMC4wMjMgYzAuMDE0LTAuMDQ4LDAuMDI5LTAuMDk0LDAuMDQ5LTAuMTM3YzAuMDAzLTAuMDA3LDAuMDA1LTAuMDEzLDAuMDEtMC4wMTljMC4wMTctMC4wMzIsMC4wMzItMC4wNjMsMC4wNTEtMC4wOTMgYzAuMDA3LTAuMDEzLDAuMDE1LTAuMDI0LDAuMDIzLTAuMDM1YzAuMDE0LTAuMDI0LDAuMDMyLTAuMDQ2LDAuMDUtMC4wNjdjMC4
wMDctMC4wMDksMC4wMTUtMC4wMTcsMC4wMjMtMC4wMjcgYzAuMDI1LTAuMDI0LDAuMDUxLTAuMDQ3LDAuMDc3LTAuMDY1YzAuMDEyLTAuMDA3LDAuMDIzLTAuMDE1LDAuMDM2LTAuMDJjMC4wMTktMC4wMTQsMC4wMzgtMC4wMjEsMC4wNTgtMC4wMyBjMC4wMTItMC4wMDYsMC4wMjUtMC4wMTEsMC4wMzctMC4wMTVjMC4wMjktMC4wMDgsMC4wNTctMC4wMTYsMC4wODgtMC4wMTljMC4wMDMsMCwwLjAwNi0wLjAwMSwwLjAxLTAuMDAxIGMwLjAzMi0wLjAwMywwLjA2NC0wL
jAwMiwwLjA5NywwLjAwM2MwLjAwNywwLjAwMSwwLjAxNSwwLjAwMywwLjAyMywwLjAwNGMwLjAyNiwwLjAwNiwwLjA1MywwLjAxMiwwLjA3OSwwLjAyMSBjMC4wMDcsMC4wMDMsMC4wMTQsMC4wMDYsMC4wMjEsMC4wMDljMC4wMzEsMC4wMTQsMC4wNjIsMC4wMzEsMC4wOTEsMC4wNTFjMC4wMDIsMC4wMDIsMC4wMDQsMC4wMDMsMC4wMDcsMC4wMDYgYzAuMDM2LDAuMDIzLDAuMDcxLDAuMDUsMC4xMDQsMC4wODNjMC42NjgsMC42NTMsMC45LDAuNzE0LDIuMzk0LDAuNjE
1YzAuNTQ2LTAuMDM3LDEuMDEyLTAuMDM4LDEuMzk0LTAuMDA3IGMwLjcwOSwwLjA2LDEuMTMxLDAuMjMsMS4yNCwwLjUxNWMwLjAzOCwwLjA5OSwwLjA1LDAuMTgsMC4wMjUsMC4yNUMyMy41MjIsMTUuODA5LDIzLjEyMiwxNS45MDQsMjIuMTIyLDE2LjAxNXogTTI5LjAwMSwxMy4zOCBjLTAuMDEsMC4wMDctMC4wMTksMC4wMTMtMC4wMzEsMC4wMTljMCwwLjAwMS0wLjAwMywwLjAwMy0wLjAwNiwwLjAwNGMtMC41MTEsMC4yNjktMS4zMjUsMC40MjktMi4xNzEsMC4zN
TggYy0wLjM0NC0wLjAyNy0wLjUyNi0wLjA4Ny0wLjU0My0wLjE2NGMtMC4wMTItMC4wNTIsMC4wNTUtMC4xMTEsMC4xOTctMC4xNzFjMC4wNy0wLjAzLDAuMTUzLTAuMDYxLDAuMjU2LTAuMDg5IGMwLjU4NC0wLjE2OSwwLjkxLTAuNjA4LDAuNTk0LTAuODA1Yy0wLjMzNy0wLjIxMi0xLjQ5Mi0wLjM0NS0yLjAwNC0wLjIzMWMtMC4yMTcsMC4wNDktMC4zNDIsMC4wNTEtMC4zNzQsMC4wMTMgYy0wLjAwMS0wLjAwMS0wLjAwNC0wLjAwMy0wLjAwNS0wLjAwNmMtMC4wMDk
tMC4wMTUtMC4wMDQtMC4wMzUsMC4wMTEtMC4wNjJjMC4wMTItMC4wMTYsMC4wMjYtMC4wMzEsMC4wNDctMC4wNDggYzAsMCwwLjAwMSwwLDAuMDAyLDBjMC4wMTktMC4wMTgsMC4wNDUtMC4wMzIsMC4wNzItMC4wNDZjMC4wMDItMC4wMDMsMC4wMDYtMC4wMDMsMC4wMS0wLjAwNmMwLjAyNy0wLjAxNCwwLjA1Ny0wLjAyNywwLjA5Mi0wLjA0MSBjMC4wMDUtMC4wMDIsMC4wMDgtMC4wMDMsMC4wMTEtMC4wMDVjMC4wMzctMC4wMTQsMC4wNzctMC4wMjgsMC4xMjEtMC4wN
DJjMC4wMDEsMCwwLjAwMy0wLjAwMiwwLjAwNS0wLjAwMiBjMC4yNzYtMC4wOSwwLjY4Mi0wLjE2NCwxLjEtMC4yMTNjMC4wMDgtMC4wMDMsMC4wMTQtMC4wMDMsMC4wMjEtMC4wMDNjMC4wNjEtMC4wMDksMC4xMjMtMC4wMTQsMC4xODYtMC4wMiBjMC4wMDktMC4wMDIsMC4wMTktMC4wMDIsMC4wMjctMC4wMDNjMC4wNjEtMC4wMDQsMC4xMTktMC4wMDksMC4xOC0wLjAxM2MwLjAwOSwwLDAuMDE5LTAuMDAyLDAuMDI3LTAuMDAyIGMwLjA2NS0wLjAwMywwLjEzMS0wLjAwNywwLjE5My0wLjAwOWMwLjAwNCwwLDAuMDA2LDAsMC4wMDYsMGMwLjIwNi0wLjAwOCwwLjQtMC4wMDIsMC41NzEsMC4wMTIgYzAuOTQ4LDAuMDg2LDEuNzE2LDAuNDIxLDEuODY4LDAuODEzYzAuMDE1LDAuMDQsMC4wMjQsMC4wOCwwLjAyNywwLjEyM0MyOS41MSwxMi45NzksMjkuMzIsMTMuMjAxLDI5LjAwMSwxMy4zOHoiLz48L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Red Hat</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="5">
<name>Ubuntu</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-ubuntu.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik00MCwyNGMwLDguOC03LjIsMTYtMTYsMTZTOCwzMi44LDgsMjRTMTUuMiw4LDI0LDhTNDAsMTUuMiw0MCwyNHoiLz48cGF0aC
BmaWxsPSIjZTY0YTE5IiBkPSJNMzAgMjRjMCAzLjMtMi43IDYtNiA2LTMuMyAwLTYtMi43LTYtNnMyLjctNiA2LTZDMjcuMyAxOCAzMCAyMC43IDMwIDI0ek0xMiAyMS41YzEuNCAwIDIuNSAxLjEgMi41IDIuNXMtMS4xIDIuNS0yLjUgMi41UzkuNSAyNS40IDkuNSAyNCAxMC42IDIxLjUgMTIgMjEuNU0xMiAyMC41Yy0xLjkgMC0zLjUgMS42LTMuNSAzLjVzMS42IDMuNSAzLjUgMy41IDMuNS0xLjYgMy41LTMuNVMxMy45IDIwLjUgMTIgMjAuNXpNMzAgMzEuNWMxLjQg
MCAyLjUgMS4xIDIuNSAyLjVzLTEuMSAyLjUtMi41IDIuNS0yLjUtMS4xLTIuNS0yLjVTMjguNiAzMS41IDMwIDMxLjVNMzAgMzAuNWMtMS45IDAtMy41IDEuNi0zLjUgMy41czEuNiAzLjUgMy41IDMuNSAzLjUtMS42IDMuNS0zLjVTMzEuOSAzMC41IDMwIDMwLjV6Ii8+PHBhdGggZmlsbD0iI2U2NGExOSIgZD0iTTI0LDRDMTMsNCw0LDEzLDQsMjRzOSwyMCwyMCwyMHMyMC05LDIwLTIwUzM1LDQsMjQsNHogTTMyLjUsMzRjMCwxLjQtMS4xLDIuNS0yLjUsMi41IHMtMi
41LTEuMS0yLjUtMi41YzAtMC4yLDAtMC41LDAuMS0wLjdDMjYuNSwzMy44LDI1LjMsMzQsMjQsMzRjLTUuMSwwLTkuMi0zLjgtOS45LTguN2MtMC40LDAuNy0xLjIsMS4yLTIuMSwxLjIgYy0xLjQsMC0yLjUtMS4xLTIuNS0yLjVzMS4xLTIuNSwyLjUtMi41YzAuOSwwLDEuNywwLjUsMi4xLDEuMmMwLjctNC45LDQuOC04LjcsOS45LTguN2MxLjMsMCwyLjUsMC4yLDMuNiwwLjcgYy0wLjEtMC4yLTAuMS0wLjQtMC4xLTAuN2MwLTEuNCwxLjEtMi41LDIuNS0yLjVzMi41
LDEuMSwyLjUsMi41YzAsMS4yLTAuOCwyLjItMiwyLjRDMzIuNywxOC4zLDM0LDIxLDM0LDI0cy0xLjMsNS43LTMuNSw3LjYgQzMxLjcsMzEuOCwzMi41LDMyLjgsMzIuNSwzNHoiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMzAgMTEuNWMxLjQgMCAyLjUgMS4xIDIuNSAyLjUgMCAxLjQtMS4xIDIuNS0yLjUgMi41cy0yLjUtMS4xLTIuNS0yLjVDMjcuNSAxMi42IDI4LjYgMTEuNSAzMCAxMS41TTMwIDEwLjVjLTEuOSAwLTMuNSAxLjYtMy41IDMuNXMxLjYgMy41ID
MuNSAzLjUgMy41LTEuNiAzLjUtMy41UzMxLjkgMTAuNSAzMCAxMC41ek0yNCAyNGMtMi42LTQuMS01LjItOC4xLTcuOC0xMi4yIi8+PHBhdGggZmlsbD0iI2U2NGExOSIgZD0iTTE5LjEgMTAuN0gyMS4xVjI1LjFIMTkuMXoiIHRyYW5zZm9ybT0icm90YXRlKC0zMi40NjcgMjAuMTI3IDE3LjkxMSkiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMjQgMjNIMzguNFYyNUgyNHoiLz48Zz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMjQsMjRjLTIuNyw0LTUuMyw4LTgsMTIiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMTIuOCAyOUgyNy4yMDAwMDAwMDAwMDAwMDNWMzFIMTIuOHoiIHRyYW5zZm9ybT0icm90YXRlKC01Ni4zMTIgMTkuOTk4IDMwLjAwNikiLz48L2c+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Ubuntu</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="6">
<name>Ubuntu server</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-ubuntu.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik00MCwyNGMwLDguOC03LjIsMTYtMTYsMTZTOCwzMi44LDgsMjRTMTUuMiw4LDI0LDhTNDAsMTUuMiw0MCwyNHoiLz48cGF0aC
BmaWxsPSIjZTY0YTE5IiBkPSJNMzAgMjRjMCAzLjMtMi43IDYtNiA2LTMuMyAwLTYtMi43LTYtNnMyLjctNiA2LTZDMjcuMyAxOCAzMCAyMC43IDMwIDI0ek0xMiAyMS41YzEuNCAwIDIuNSAxLjEgMi41IDIuNXMtMS4xIDIuNS0yLjUgMi41UzkuNSAyNS40IDkuNSAyNCAxMC42IDIxLjUgMTIgMjEuNU0xMiAyMC41Yy0xLjkgMC0zLjUgMS42LTMuNSAzLjVzMS42IDMuNSAzLjUgMy41IDMuNS0xLjYgMy41LTMuNVMxMy45IDIwLjUgMTIgMjAuNXpNMzAgMzEuNWMxLjQg
MCAyLjUgMS4xIDIuNSAyLjVzLTEuMSAyLjUtMi41IDIuNS0yLjUtMS4xLTIuNS0yLjVTMjguNiAzMS41IDMwIDMxLjVNMzAgMzAuNWMtMS45IDAtMy41IDEuNi0zLjUgMy41czEuNiAzLjUgMy41IDMuNSAzLjUtMS42IDMuNS0zLjVTMzEuOSAzMC41IDMwIDMwLjV6Ii8+PHBhdGggZmlsbD0iI2U2NGExOSIgZD0iTTI0LDRDMTMsNCw0LDEzLDQsMjRzOSwyMCwyMCwyMHMyMC05LDIwLTIwUzM1LDQsMjQsNHogTTMyLjUsMzRjMCwxLjQtMS4xLDIuNS0yLjUsMi41IHMtMi
41LTEuMS0yLjUtMi41YzAtMC4yLDAtMC41LDAuMS0wLjdDMjYuNSwzMy44LDI1LjMsMzQsMjQsMzRjLTUuMSwwLTkuMi0zLjgtOS45LTguN2MtMC40LDAuNy0xLjIsMS4yLTIuMSwxLjIgYy0xLjQsMC0yLjUtMS4xLTIuNS0yLjVzMS4xLTIuNSwyLjUtMi41YzAuOSwwLDEuNywwLjUsMi4xLDEuMmMwLjctNC45LDQuOC04LjcsOS45LTguN2MxLjMsMCwyLjUsMC4yLDMuNiwwLjcgYy0wLjEtMC4yLTAuMS0wLjQtMC4xLTAuN2MwLTEuNCwxLjEtMi41LDIuNS0yLjVzMi41
LDEuMSwyLjUsMi41YzAsMS4yLTAuOCwyLjItMiwyLjRDMzIuNywxOC4zLDM0LDIxLDM0LDI0cy0xLjMsNS43LTMuNSw3LjYgQzMxLjcsMzEuOCwzMi41LDMyLjgsMzIuNSwzNHoiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMzAgMTEuNWMxLjQgMCAyLjUgMS4xIDIuNSAyLjUgMCAxLjQtMS4xIDIuNS0yLjUgMi41cy0yLjUtMS4xLTIuNS0yLjVDMjcuNSAxMi42IDI4LjYgMTEuNSAzMCAxMS41TTMwIDEwLjVjLTEuOSAwLTMuNSAxLjYtMy41IDMuNXMxLjYgMy41ID
MuNSAzLjUgMy41LTEuNiAzLjUtMy41UzMxLjkgMTAuNSAzMCAxMC41ek0yNCAyNGMtMi42LTQuMS01LjItOC4xLTcuOC0xMi4yIi8+PHBhdGggZmlsbD0iI2U2NGExOSIgZD0iTTE5LjEgMTAuN0gyMS4xVjI1LjFIMTkuMXoiIHRyYW5zZm9ybT0icm90YXRlKC0zMi40NjcgMjAuMTI3IDE3LjkxMSkiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMjQgMjNIMzguNFYyNUgyNHoiLz48Zz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMjQsMjRjLTIuNyw0LTUuMyw4LTgsMTIiLz48cGF0aCBmaWxsPSIjZTY0YTE5IiBkPSJNMTIuOCAyOUgyNy4yMDAwMDAwMDAwMDAwMDNWMzFIMTIuOHoiIHRyYW5zZm9ybT0icm90YXRlKC01Ni4zMTIgMTkuOTk4IDMwLjAwNikiLz48L2c+PC9zdmc+Cg==</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Ubuntu server</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="7">
<name>vCenter Server</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-vmware.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNTAgNTAiIHdpZHRoPSI1MHB4IiBoZWlnaHQ9IjUwcHgiPjxwYXRoIGQ9Ik0gNDIuNDE0MDYzIDE1IEMgMzguODI0MjE5IDE1IDM2LjU3NDIxOSAxNy41IDM2LjU3NDIxOSAxNy41IEMgMzUuMzc4OTA2IDE1Ljk0MTQwNiAzMy43MzA0NjkgMTUuMDAzOTA2IDMwLjk0MTQwNiAxNS4wMDM5MDYgQyAyNy45OTYwOTQgMTUuMDAzOTA2IDI2LjA0Mjk2OSAxNy41IDI2LjA0Mjk2OSAxNy41IEMgMjQuODQ3NjU2IDE1Ljk0MTQwNiAyMi42ODc1IDE1IDIxIDE1IEMgMTguMzkwNjI1IDE1IDE2LjMyMDMxMyAxNi4xNTIzNDQgMTUuMDU0Njg4IDE5LjA1ODU5NCBMIDEwLjgyMDMxMyAyOC4zMjAzMTMgTCA2LjAzMTI1IDE2LjU1ODU5NCBDIDUuNDI1NzgxIDE1LjIyNjU2MyAzLjkzMzU5NCAxNC42MjUgMi41NDI5NjkgMTUuMjQ2MDk0IEMgMS4xNDg0MzggMTUuODcxMDk0IDAuNjM2NzE5IDE3LjQyNTc4MSAxLjI2NTYyNSAxOC43NTc4MTMgTCA3LjExMzI4MSAzMS45NDUzMTMgQyA4LjAzMTI1IDMzLjk0OTIxOSA5LjAwMzkwNiAzNSAxMC44MjAzMTMgMzUgQyAxMi43NjU2MjUgMzUgMTMuNjA5Mzc1IDMzLjg1NTQ2OSAxNC41MzEyNSAzMS45NDUzMTMgQyAxNC41MzEyNSAzMS45NDUzMTMgMTguNTExNzE5IDIzLjA2MjUgMTkgMjIgQyAxOS40ODgyODEgMjAuOTM3NSAyMC4zMDA3ODEgMjAgMjEuNSAyMCBDIDIyLjg3NSAyMCAyNCAyMS4xMjUgMjQgMjIuNSBMIDI0IDMyLjM3NSBDIDI0IDMzLjgyMDMxMyAyNS4wODU5MzggMzUgMjYuNTIzNDM4IDM1IEMgMjcuOTU3MDMxIDM1IDI5IDMzLjgyMDMxMyAyOSAzMi4zNzUgTCAyOSAyMi41IEMgMjkgMjEuMTI1IDMwLjEyNSAyMCAzMS41IDIwIEMgMzIuODc1IDIwIDM0IDIxLjEyNSAzNCAyMi41IEwgMzQgMzIuNSBDIDM0IDMzLjg3NSAzNS4xMjUgMzUgMzYuNSAzNSBDIDM3Ljg3NSAzNSAzOSAzMy44NzUgMzkgMzIuNSBMIDM5IDIyLjUgQyAzOSAyMS4xMjUgNDAuMTI1IDIwIDQxLjUgMjAgQyA0Mi44NzUgMjAgNDQgMjEuMTI1IDQ0IDIyLjUgTCA0NCAzMi41IEMgNDQgMzMuODc1IDQ1LjEyNSAzNSA0Ni41IDM1IEMgNDcuODc1IDM1IDQ5IDMzLjg3NSA0OSAzMi41IEwgNDkgMjEuMzU1NDY5IEMgNDkgMTcuNjE3MTg4IDQ2LjAxMTcxOSAxNSA0Mi40MTQwNjMgMTUgWiIvPjwvc3ZnPgo=</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>vCenter Server</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="8">
<name>Windows</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-windows.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMxOTc2ZDIiIGQ9Ik02LDZoMTd2MTdINlY2eiIvPjxwYXRoIGZpbGw9IiMxOTc2ZDIiIGQ9Ik0yNS4wNDIsMjIuOTU4VjZINDJ2MTYuOTU4SDI1LjA0MnoiLz48cGF0aCBmaWxsPSIjMTk3NmQyIiBkPSJNNiwyNWgxN3YxN0g2VjI1eiIvPjxwYXRoIGZpbGw9IiMxOTc2ZDIiIGQ9Ik0yNSw0MlYyNWgxN3YxN0gyNXoiLz48L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Windows</friendlyname>
</OSFamily>
<OSFamily alias="OSFamily" id="9">
<name>Windows server</name>
<logo><mimetype>image/svg+xml</mimetype><filename>icons8-windows-server.svg</filename><data>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiMwMGIwZmYiIGQ9Ik0yMCAyNS4wMjZMNS4wMTEgMjUgNS4wMTIgMzcuNzQ0IDIwIDM5LjgxOHpNMjIgMjUuMDNMMjIgNDAuMDk1IDQyLjk5NSA0MyA0MyAyNS4wNjZ6TTIwIDguMjU2TDUgMTAuMzggNS4wMTQgMjMgMjAgMjN6TTIyIDcuOTczTDIyIDIzIDQyLjk5NSAyMyA0Mi45OTUgNXoiLz48L3N2Zz4K</data><downloads_count>0</downloads_count></logo>
<finalclass>OS Family</finalclass>
<friendlyname>Windows server</friendlyname>
</OSFamily>
</Set>

View File

@@ -4461,6 +4461,9 @@
<attribute id="name"/>
</attributes>
</naming>
<fields_semantic>
<image_attribute>logo</image_attribute>
</fields_semantic>
<style>
<icon/>
</style>
@@ -4470,7 +4473,15 @@
</attributes>
</reconciliation>
</properties>
<fields/>
<fields>
<field id="logo" xsi:type="AttributeImage">
<display_max_width>96</display_max_width>
<display_max_height>96</display_max_height>
<storage_max_width>128</storage_max_width>
<storage_max_height>128</storage_max_height>
<is_null_allowed>true</is_null_allowed>
</field>
</fields>
<methods/>
<presentation>
<details>
@@ -4478,6 +4489,9 @@
<item id="name">
<rank>10</rank>
</item>
<item id="logo">
<rank>20</rank>
</item>
</items>
</details>
<search>
@@ -4492,6 +4506,9 @@
<item id="name">
<rank>10</rank>
</item>
<item id="logo">
<rank>20</rank>
</item>
</items>
</list>
</presentation>
@@ -4574,6 +4591,9 @@
<item id="name">
<rank>10</rank>
</item>
<item id="logo">
<rank>20</rank>
</item>
</items>
</list>
<summary>

View File

@@ -579,7 +579,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
//
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:WebServer' => 'Web server',
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => '',
'Class:WebServer/Attribute:webapp_list' => 'Web aplikace',
'Class:WebServer/Attribute:webapp_list+' => 'Všechny webové aplikace dostupné na tomto web serveru',

View File

@@ -103,7 +103,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:FunctionalCI' => 'Functional CI',
'Class:FunctionalCI+' => '',
'Class:FunctionalCI+' => 'Abstract class grouping multiple types of Configuration Items.',
'Class:FunctionalCI/Attribute:name' => 'Name',
'Class:FunctionalCI/Attribute:name+' => '',
'Class:FunctionalCI/Attribute:description' => 'Description',
@@ -142,7 +142,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PhysicalDevice' => 'Physical Device',
'Class:PhysicalDevice+' => '',
'Class:PhysicalDevice+' => 'Abstract class grouping physical types of Configuration Items. A Physical Device can be located. It has usually a Brand and Model.',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s',
'Class:PhysicalDevice/Attribute:serialnumber' => 'Serial number',
'Class:PhysicalDevice/Attribute:serialnumber+' => '',
@@ -182,7 +182,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Rack' => 'Rack',
'Class:Rack+' => '',
'Class:Rack+' => 'A physical container for Datacenter Devices and Enclosures.',
'Class:Rack/ComplementaryName' => '%1$s - %2$s',
'Class:Rack/Attribute:nb_u' => 'Rack units',
'Class:Rack/Attribute:nb_u+' => '',
@@ -198,7 +198,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:TelephonyCI' => 'Telephony CI',
'Class:TelephonyCI+' => '',
'Class:TelephonyCI+' => 'Abstract class grouping telephony devices',
'Class:TelephonyCI/Attribute:phonenumber' => 'Phone number',
'Class:TelephonyCI/Attribute:phonenumber+' => '',
]);
@@ -209,7 +209,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Phone' => 'Phone',
'Class:Phone+' => '',
'Class:Phone+' => 'End User device. Plain wired phone',
]);
//
@@ -218,7 +218,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:MobilePhone' => 'Mobile Phone',
'Class:MobilePhone+' => '',
'Class:MobilePhone+' => 'End User device. Wireless phone',
'Class:MobilePhone/Attribute:imei' => 'IMEI',
'Class:MobilePhone/Attribute:imei+' => '',
'Class:MobilePhone/Attribute:hw_pin' => 'Hardware PIN',
@@ -231,7 +231,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:IPPhone' => 'IP Phone',
'Class:IPPhone+' => '',
'Class:IPPhone+' => 'Physical device dedicated to phone calls, connected to a network',
]);
//
@@ -240,7 +240,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Tablet' => 'Tablet',
'Class:Tablet+' => '',
'Class:Tablet+' => 'End User device. For example iPad, Galaxy Note/Tab Nexus, Kindle...',
]);
//
@@ -249,7 +249,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:ConnectableCI' => 'Connectable CI',
'Class:ConnectableCI+' => 'Physical CI',
'Class:ConnectableCI+' => 'Physical Device which can be connected to a network.',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s',
'Class:ConnectableCI/Attribute:networkdevice_list' => 'Network devices',
'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device',
@@ -263,7 +263,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DatacenterDevice' => 'Datacenter Device',
'Class:DatacenterDevice+' => '',
'Class:DatacenterDevice+' => 'Connectable CI which can be racked in a datacenter',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s',
'Class:DatacenterDevice/Attribute:rack_id' => 'Rack',
'Class:DatacenterDevice/Attribute:rack_id+' => '',
@@ -302,7 +302,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:NetworkDevice' => 'Network Device',
'Class:NetworkDevice+' => '',
'Class:NetworkDevice+' => 'Any type of network device: router, switch, hub, load balancer, firewall…',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s',
'Class:NetworkDevice/Attribute:networkdevicetype_id' => 'Network type',
'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '',
@@ -324,7 +324,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Server' => 'Server',
'Class:Server+' => '',
'Class:Server+' => 'Datacenter Device managing access to centralized resources or services. It contains an OS Version executing Software Instances.',
'Class:Server/ComplementaryName' => '%1$s - %2$s',
'Class:Server/Attribute:osfamily_id' => 'OS family',
'Class:Server/Attribute:osfamily_id+' => '',
@@ -352,7 +352,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:StorageSystem' => 'Storage System',
'Class:StorageSystem+' => '',
'Class:StorageSystem+' => 'Datacenter Device. Network switch compatible with the Fibre Channel protocol used by storage networks.',
'Class:StorageSystem/ComplementaryName' => '%1$s - %2$s',
'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logical volumes',
'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system',
@@ -364,7 +364,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:SANSwitch' => 'SAN Switch',
'Class:SANSwitch+' => '',
'Class:SANSwitch+' => 'A SAN Switch is a network switch compatible with the Fibre Channel protocol used by storage networks. It is a Datacenter Device.',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s',
'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Devices',
'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch',
@@ -376,7 +376,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:TapeLibrary' => 'Tape Library',
'Class:TapeLibrary+' => '',
'Class:TapeLibrary+' => 'Datacenter Device which hosts multiple magnetic Tapes (or cartridge). Tape Libraries are used for data backup or archiving.',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s',
'Class:TapeLibrary/Attribute:tapes_list' => 'Tapes',
'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library',
@@ -388,7 +388,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:NAS' => 'NAS',
'Class:NAS+' => '',
'Class:NAS+' => 'Datacenter Device. High-capacity storage device connected to a network. In '.ITOP_APPLICATION_SHORT.' a NAS (Network-attached storage) is linked to NAS File Systems.',
'Class:NAS/ComplementaryName' => '%1$s - %2$s',
'Class:NAS/Attribute:nasfilesystem_list' => 'Filesystems',
'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS',
@@ -400,7 +400,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PC' => 'PC',
'Class:PC+' => '',
'Class:PC+' => 'Connectable CI. A Personal Computer (PC) is a Physical Device, Desktop or Laptop, running an operating system and designed to execute Software Instances.',
'Class:PC/ComplementaryName' => '%1$s - %2$s',
'Class:PC/Attribute:osfamily_id' => 'OS family',
'Class:PC/Attribute:osfamily_id+' => '',
@@ -428,7 +428,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Printer' => 'Printer',
'Class:Printer+' => '',
'Class:Printer+' => 'Connectable CI. Physical Device connected either to the network or to a PC.',
'Class:Printer/ComplementaryName' => '%1$s - %2$s',
]);
@@ -438,7 +438,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PowerConnection' => 'Power Connection',
'Class:PowerConnection+' => '',
'Class:PowerConnection+' => 'Abstract class grouping physical devices used for electrical power supply.',
'Class:PowerConnection/ComplementaryName' => '%1$s - %2$s',
]);
@@ -448,7 +448,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PowerSource' => 'Power Source',
'Class:PowerSource+' => '',
'Class:PowerSource+' => 'Physical Power Connection. Used in a datacenter to document any kind of power source (main power inlet, breaker…) that is not a PDU.',
'Class:PowerSource/ComplementaryName' => '%1$s - %2$s',
'Class:PowerSource/Attribute:pdus_list' => 'PDUs',
'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source',
@@ -460,7 +460,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PDU' => 'PDU',
'Class:PDU+' => '',
'Class:PDU+' => 'Power Connection. PDU (Power Distribution Unit) is a device fitted with multiple outputs designed to distribute electric power, especially to racks of computers and networking equipment located within a datacenter.',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s',
'Class:PDU/Attribute:rack_id' => 'Rack',
'Class:PDU/Attribute:rack_id+' => '',
@@ -478,7 +478,8 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Peripheral' => 'Peripheral',
'Class:Peripheral+' => '',
'Class:Peripheral+' => 'Physical device, used to document any kind of computer peripheral.
For example: external hard drives, scanners, input devices (trackballs, bar code scanners), etc…',
'Class:Peripheral/ComplementaryName' => '%1$s - %2$s',
]);
@@ -488,7 +489,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Enclosure' => 'Enclosure',
'Class:Enclosure+' => '',
'Class:Enclosure+' => 'Physical Device. Cabinet containing baffles, fans... which can be mounted inside a Rack or directly fitted on the wall of a datacenter.',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s',
'Class:Enclosure/Attribute:rack_id' => 'Rack',
'Class:Enclosure/Attribute:rack_id+' => '',
@@ -506,7 +507,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:ApplicationSolution' => 'Application Solution',
'Class:ApplicationSolution+' => '',
'Class:ApplicationSolution+' => 'Application Solutions describe complex applications that are made of (or depend on) several basic components. The main information conveyed by an Application Solution is its list of relationships.',
'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs',
'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution',
'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Business processes',
@@ -529,7 +530,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:BusinessProcess' => 'Business Process',
'Class:BusinessProcess+' => '',
'Class:BusinessProcess+' => 'A Business Process is used to document a high-level process or an important application for the operations. It is quite similar to an Application Solution but for describing higher level applications or whole processes in the organization.',
'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Application solutions',
'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process',
'Class:BusinessProcess/Attribute:status' => 'Status',
@@ -540,13 +541,49 @@ Dict::Add('EN US', 'English', 'English', [
'Class:BusinessProcess/Attribute:status/Value:inactive+' => 'inactive',
]);
//
// Class: Software
//
Dict::Add('EN US', 'English', 'English', [
'Class:Software' => 'Software',
'Class:Software+' => 'Software is a generic item in the software catalog. It has a particular version. In '.ITOP_APPLICATION_SHORT.' a Software has a category amongst: DB Server, Middleware, PC Software, Web Server and Other Software.',
'Class:Software/ComplementaryName' => '%1$s - %2$s',
'Class:Software/Attribute:name' => 'Name',
'Class:Software/Attribute:name+' => '',
'Class:Software/Attribute:vendor' => 'Vendor',
'Class:Software/Attribute:vendor+' => '',
'Class:Software/Attribute:version' => 'Version',
'Class:Software/Attribute:version+' => '',
'Class:Software/Attribute:documents_list' => 'Documents',
'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software',
'Class:Software/Attribute:type' => 'Type',
'Class:Software/Attribute:type+' => '',
'Class:Software/Attribute:type/Value:DBServer' => 'DB Server',
'Class:Software/Attribute:type/Value:DBServer+' => 'DB Server',
'Class:Software/Attribute:type/Value:Middleware' => 'Middleware',
'Class:Software/Attribute:type/Value:Middleware+' => 'Middleware',
'Class:Software/Attribute:type/Value:OtherSoftware' => 'Other Software',
'Class:Software/Attribute:type/Value:OtherSoftware+' => 'Other Software',
'Class:Software/Attribute:type/Value:PCSoftware' => 'PC Software',
'Class:Software/Attribute:type/Value:PCSoftware+' => 'PC Software',
'Class:Software/Attribute:type/Value:WebServer' => 'Web Server',
'Class:Software/Attribute:type/Value:WebServer+' => 'Web Server',
'Class:Software/Attribute:softwareinstance_list' => 'Software Instances',
'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software',
'Class:Software/Attribute:softwarepatch_list' => 'Software Patches',
'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software',
'Class:Software/Attribute:softwarelicence_list' => 'Software Licenses',
'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software',
]);
//
// Class: SoftwareInstance
//
Dict::Add('EN US', 'English', 'English', [
'Class:SoftwareInstance' => 'Software Instance',
'Class:SoftwareInstance+' => '',
'Class:SoftwareInstance+' => 'Abstract class representing the deployment of a Software on a device (Server, PC, VirtualMachine). In '.ITOP_APPLICATION_SHORT.' there are different types of Software Instance: DB Server, Middleware, PC Software, Web Server and Other Software',
'Class:SoftwareInstance/Attribute:system_id' => 'System',
'Class:SoftwareInstance/Attribute:system_id+' => 'The system can be a Server, a Virtual Machine, a PC, ...',
'Class:SoftwareInstance/Attribute:system_name' => 'System name',
@@ -575,7 +612,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Middleware' => 'Middleware',
'Class:Middleware+' => '',
'Class:Middleware+' => 'Software Instance offering services to other software (like: Tomcat, JBoss, Talend, Microsoft BizTalk, IBM Websphere or Lotus Domino) installed on a particular system (PC, Server or Virtual Machine).',
'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware instances',
'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware',
]);
@@ -586,7 +623,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DBServer' => 'DB Server',
'Class:DBServer+' => '',
'Class:DBServer+' => 'Software Instance offering Web services (like Apache 2.4, Nginx 1.29.4, IIS 7.0) installed on a specific system (PC, Server or Virtual Machine).',
'Class:DBServer/Attribute:dbschema_list' => 'DB schemas',
'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server',
]);
@@ -596,8 +633,8 @@ Dict::Add('EN US', 'English', 'English', [
//
Dict::Add('EN US', 'English', 'English', [
'Class:WebServer' => 'Web server',
'Class:WebServer+' => '',
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => 'It is a Software Instance, offering Web services (like Apache 2.4, Nginx 1.29.4, IIS 7.0) installed on a specific system (PC, Server or Virtual Machine).',
'Class:WebServer/Attribute:webapp_list' => 'Web applications',
'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server',
]);
@@ -608,7 +645,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PCSoftware' => 'PC Software',
'Class:PCSoftware+' => '',
'Class:PCSoftware+' => 'Software Instance for software (like MS Office, Adobe Photoshop or Filezilla) installed on a PC.',
]);
//
@@ -617,7 +654,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OtherSoftware' => 'Other Software',
'Class:OtherSoftware+' => '',
'Class:OtherSoftware+' => 'Any type of Software Instance that do not fit in the other categories: PC Software, Middleware, DB server or Web Server.',
]);
//
@@ -626,7 +663,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:MiddlewareInstance' => 'Middleware Instance',
'Class:MiddlewareInstance+' => '',
'Class:MiddlewareInstance+' => 'Functional CI representing a piece of one Middleware. A Middleware being in '.ITOP_APPLICATION_SHORT.' is a Software Instance offering services to other software.',
'Class:MiddlewareInstance/ComplementaryName' => '%1$s - %2$s',
'Class:MiddlewareInstance/Attribute:middleware_id' => 'Middleware',
'Class:MiddlewareInstance/Attribute:middleware_id+' => '',
@@ -640,7 +677,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DatabaseSchema' => 'Database Schema',
'Class:DatabaseSchema+' => '',
'Class:DatabaseSchema+' => 'Functional CI. Dabatase instance running of a specific DB server.',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s',
'Class:DatabaseSchema/Attribute:dbserver_id' => 'DB server',
'Class:DatabaseSchema/Attribute:dbserver_id+' => '',
@@ -654,7 +691,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:WebApplication' => 'Web Application',
'Class:WebApplication+' => '',
'Class:WebApplication+' => 'Functional CI. Instance of an application accessible using a web browser and that runs on a given Web Server instance. For eg. this iTop that you\'re looking at.',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s',
'Class:WebApplication/Attribute:webserver_id' => 'Web server',
'Class:WebApplication/Attribute:webserver_id+' => '',
@@ -670,7 +707,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:VirtualDevice' => 'Virtual Device',
'Class:VirtualDevice+' => '',
'Class:VirtualDevice+' => 'Functional CI. Abstract class used for server virtualization.',
'Class:VirtualDevice/Attribute:status' => 'Status',
'Class:VirtualDevice/Attribute:status+' => '',
'Class:VirtualDevice/Attribute:status/Value:implementation' => 'implementation',
@@ -691,7 +728,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:VirtualHost' => 'Virtual Host',
'Class:VirtualHost+' => '',
'Class:VirtualHost+' => 'Virtual Device. Abstract class used for devices hosting Virtual Machines.',
'Class:VirtualHost/Attribute:virtualmachine_list' => 'Virtual machines',
'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host',
]);
@@ -702,7 +739,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Hypervisor' => 'Hypervisor',
'Class:Hypervisor+' => '',
'Class:Hypervisor+' => 'Virtual Host. Virtualization software (MS Hyper-V, VMWare ESX, Xen, etc.), running on a physical Server and supporting the creation of Virtual Machines.',
'Class:Hypervisor/Attribute:farm_id' => 'Farm',
'Class:Hypervisor/Attribute:farm_id+' => '',
'Class:Hypervisor/Attribute:farm_name' => 'Farm name',
@@ -719,7 +756,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Farm' => 'Farm',
'Class:Farm+' => '',
'Class:Farm+' => 'Virtual Host. A Farm (or cluster) is a group of Hypervisors pooled together and sharing storage resources to provide an overall fault tolerant system for hosting Virtual Machines.',
'Class:Farm/Attribute:hypervisor_list' => 'Hypervisors',
'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm',
'Class:Farm/Attribute:redundancy' => 'High availability',
@@ -734,7 +771,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:VirtualMachine' => 'Virtual Machine',
'Class:VirtualMachine+' => '',
'Class:VirtualMachine+' => 'Virtual Device. Virtual equivalent to a Server, it is hosted either on an Hypervisor or on a Farm.',
'Class:VirtualMachine/ComplementaryName' => '%1$s - %2$s',
'Class:VirtualMachine/Attribute:virtualhost_id' => 'Virtual host',
'Class:VirtualMachine/Attribute:virtualhost_id+' => '',
@@ -768,7 +805,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:LogicalVolume' => 'Logical Volume',
'Class:LogicalVolume+' => '',
'Class:LogicalVolume+' => 'The unit of storage managed inside a Storage System.',
'Class:LogicalVolume/Attribute:name' => 'Name',
'Class:LogicalVolume/Attribute:name+' => '',
'Class:LogicalVolume/Attribute:lun_id' => 'LUN ID',
@@ -857,7 +894,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Tape' => 'Tape',
'Class:Tape+' => '',
'Class:Tape+' => 'A Tape (or cartridge) within '.ITOP_APPLICATION_SHORT.' is removable piece of storage part of a Tape Library. ',
'Class:Tape/Attribute:name' => 'Name',
'Class:Tape/Attribute:name+' => '',
'Class:Tape/Attribute:description' => 'Description',
@@ -876,7 +913,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:NASFileSystem' => 'NAS File System',
'Class:NASFileSystem+' => '',
'Class:NASFileSystem+' => 'Represents a shared file system hosted inside a given NAS (Network Attached Storage).',
'Class:NASFileSystem/Attribute:name' => 'Name',
'Class:NASFileSystem/Attribute:name+' => '',
'Class:NASFileSystem/Attribute:description' => 'Description',
@@ -891,49 +928,13 @@ Dict::Add('EN US', 'English', 'English', [
'Class:NASFileSystem/Attribute:nas_name+' => '',
]);
//
// Class: Software
//
Dict::Add('EN US', 'English', 'English', [
'Class:Software' => 'Software',
'Class:Software+' => '',
'Class:Software/ComplementaryName' => '%1$s - %2$s',
'Class:Software/Attribute:name' => 'Name',
'Class:Software/Attribute:name+' => '',
'Class:Software/Attribute:vendor' => 'Vendor',
'Class:Software/Attribute:vendor+' => '',
'Class:Software/Attribute:version' => 'Version',
'Class:Software/Attribute:version+' => '',
'Class:Software/Attribute:documents_list' => 'Documents',
'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software',
'Class:Software/Attribute:type' => 'Type',
'Class:Software/Attribute:type+' => '',
'Class:Software/Attribute:type/Value:DBServer' => 'DB Server',
'Class:Software/Attribute:type/Value:DBServer+' => 'DB Server',
'Class:Software/Attribute:type/Value:Middleware' => 'Middleware',
'Class:Software/Attribute:type/Value:Middleware+' => 'Middleware',
'Class:Software/Attribute:type/Value:OtherSoftware' => 'Other Software',
'Class:Software/Attribute:type/Value:OtherSoftware+' => 'Other Software',
'Class:Software/Attribute:type/Value:PCSoftware' => 'PC Software',
'Class:Software/Attribute:type/Value:PCSoftware+' => 'PC Software',
'Class:Software/Attribute:type/Value:WebServer' => 'Web Server',
'Class:Software/Attribute:type/Value:WebServer+' => 'Web Server',
'Class:Software/Attribute:softwareinstance_list' => 'Software Instances',
'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software',
'Class:Software/Attribute:softwarepatch_list' => 'Software Patches',
'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software',
'Class:Software/Attribute:softwarelicence_list' => 'Software Licenses',
'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software',
]);
//
// Class: Patch
//
Dict::Add('EN US', 'English', 'English', [
'Class:Patch' => 'Patch',
'Class:Patch+' => '',
'Class:Patch+' => 'Abstract class, for patch, hotfix, security fix or service pack for an OS or a Software.',
'Class:Patch/Attribute:name' => 'Name',
'Class:Patch/Attribute:name+' => '',
'Class:Patch/Attribute:documents_list' => 'Documents',
@@ -950,7 +951,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OSPatch' => 'OS Patch',
'Class:OSPatch+' => '',
'Class:OSPatch+' => 'Patch, hotfix, security fix or service pack for a given operating system.',
'Class:OSPatch/Attribute:functionalcis_list' => 'Devices',
'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed',
'Class:OSPatch/Attribute:osversion_id' => 'OS version',
@@ -965,7 +966,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:SoftwarePatch' => 'Software Patch',
'Class:SoftwarePatch+' => '',
'Class:SoftwarePatch+' => 'Patch, hotfix, security fix or service pack for a given software.',
'Class:SoftwarePatch/Attribute:software_id' => 'Software',
'Class:SoftwarePatch/Attribute:software_id+' => '',
'Class:SoftwarePatch/Attribute:software_name' => 'Software name',
@@ -980,8 +981,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Licence' => 'License',
'Class:Licence+' => '',
'Class:Licence+' => 'Abstract class. A license contract for a particular OS version or Software',
'Class:Licence/Attribute:name' => 'Name',
'Class:Licence/Attribute:name+' => '',
'Class:Licence/Attribute:documents_list' => 'Documents',
@@ -1016,7 +1016,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OSLicence' => 'OS License',
'Class:OSLicence+' => '',
'Class:OSLicence+' => 'A license contract for a particular operating system. The license is related to one operating system (for example Windows 2008 R2) and can be associated with several servers or virtual machines.',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s',
'Class:OSLicence/Attribute:osversion_id' => 'OS version',
'Class:OSLicence/Attribute:osversion_id+' => '',
@@ -1034,7 +1034,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:SoftwareLicence' => 'Software License',
'Class:SoftwareLicence+' => '',
'Class:SoftwareLicence+' => 'A license contract for a particular software. The license is related to one software (for example MS Office 2010) and can be associated with several instances of this software.',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s',
'Class:SoftwareLicence/Attribute:software_id' => 'Software',
'Class:SoftwareLicence/Attribute:software_id+' => '',
@@ -1068,7 +1068,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OSVersion' => 'OS Version',
'Class:OSVersion+' => '',
'Class:OSVersion+' => 'Typology. List of the possible values for the "OS Version" of a computer (Server, Virtual Machine or PC). The OS Versions are organized per OS Family.',
'Class:OSVersion/Attribute:osfamily_id' => 'OS family',
'Class:OSVersion/Attribute:osfamily_id+' => '',
'Class:OSVersion/Attribute:osfamily_name' => 'OS family name',
@@ -1081,7 +1081,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OSFamily' => 'OS Family',
'Class:OSFamily+' => '',
'Class:OSFamily+' => 'Typology. List of the possible values for the "OS Family" attribute of Servers, Virtual Machines and PCs.',
]);
//
@@ -1090,7 +1090,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Brand' => 'Brand',
'Class:Brand+' => '',
'Class:Brand+' => 'Typology. List of the possible values for the "Brand" attribute of Physical Device.',
'Class:Brand/Attribute:logo' => 'Logo',
'Class:Brand/Attribute:logo+' => '',
'Class:Brand/Attribute:physicaldevices_list' => 'Physical devices',
@@ -1104,8 +1104,8 @@ Dict::Add('EN US', 'English', 'English', [
//
Dict::Add('EN US', 'English', 'English', [
'Class:Model' => 'Model',
'Class:Model+' => '',
'Class:Model' => 'Device Model',
'Class:Model+' => 'Typology. List the possible values for the "Model" attribute of a Physical Device. Each Model belongs to a single Brand, and usually applies to a single type of Physical Devices.',
'Class:Model/ComplementaryName' => '%1$s - %2$s',
'Class:Model/Attribute:brand_id' => 'Brand',
'Class:Model/Attribute:brand_id+' => '',
@@ -1163,7 +1163,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:NetworkDeviceType' => 'Network Device Type',
'Class:NetworkDeviceType+' => '',
'Class:NetworkDeviceType+' => 'Typology. The possible values for the "Type" of a Network Device (e.g. Router, Switch, Firewall, etc.).',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Network devices',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type',
]);
@@ -1174,7 +1174,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:IOSVersion' => 'IOS Version',
'Class:IOSVersion+' => '',
'Class:IOSVersion+' => 'Typology. Possible values for the types of operating system for network devices (IOS from Cisco\'s Internetwork Operating System).',
'Class:IOSVersion/Attribute:brand_id' => 'Brand',
'Class:IOSVersion/Attribute:brand_id+' => '',
'Class:IOSVersion/Attribute:brand_name' => 'Brand name',
@@ -1259,7 +1259,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Subnet' => 'Subnet',
'Class:Subnet+' => '',
'Class:Subnet+' => 'Segment of an IP network, defined by an IP address and a mask',
'Class:Subnet/Name' => '%1$s/%2$s',
'Class:Subnet/ComplementaryName' => '%1$s - %2$s',
'Class:Subnet/Attribute:description' => 'Description',
@@ -1284,7 +1284,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:VLAN' => 'VLAN',
'Class:VLAN+' => '',
'Class:VLAN+' => 'A Virtual LAN is used to group together in a logical way networks Subnets and Physical Interfaces that participate in the same VLAN.',
'Class:VLAN/Attribute:vlan_tag' => 'VLAN Tag',
'Class:VLAN/Attribute:vlan_tag+' => '',
'Class:VLAN/Attribute:description' => 'Description',
@@ -1325,7 +1325,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:NetworkInterface' => 'Network Interface',
'Class:NetworkInterface+' => '',
'Class:NetworkInterface+' => 'Abstract class for all types of network interfaces.',
'Class:NetworkInterface/Attribute:name' => 'Name',
'Class:NetworkInterface/Attribute:name+' => '',
'Class:NetworkInterface/Attribute:finalclass' => 'NetworkInterface sub-class',
@@ -1338,7 +1338,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:IPInterface' => 'IP Interface',
'Class:IPInterface+' => '',
'Class:IPInterface+' => 'Abstract class. A type of Network Interface with an IP address',
'Class:IPInterface/Attribute:ipaddress' => 'IP address',
'Class:IPInterface/Attribute:ipaddress+' => '',
@@ -1360,12 +1360,16 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:PhysicalInterface' => 'Physical Interface',
'Class:PhysicalInterface+' => '',
'Class:PhysicalInterface+' => 'A type of IP Interface that represents a physical network interface (e.g. an Ethernet card).',
'Class:PhysicalInterface/Name' => '%2$s %1$s',
'Class:PhysicalInterface/Attribute:connectableci_id' => 'Device',
'Class:PhysicalInterface/Attribute:connectableci_id+' => '',
'Class:PhysicalInterface/Attribute:connectableci_name' => 'Device name',
'Class:PhysicalInterface/Attribute:connectableci_name+' => '',
'Class:PhysicalInterface/Attribute:org_id' => 'Org id',
'Class:PhysicalInterface/Attribute:org_id+' => '',
'Class:PhysicalInterface/Attribute:location_id' => 'Location id',
'Class:PhysicalInterface/Attribute:location_id+' => '',
'Class:PhysicalInterface/Attribute:vlans_list' => 'VLANs',
'Class:PhysicalInterface/Attribute:vlans_list+' => '',
]);
@@ -1398,7 +1402,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:LogicalInterface' => 'Logical Interface',
'Class:LogicalInterface+' => '',
'Class:LogicalInterface+' => 'IP Interface which is not associated permanently with a particular physical port, the association is dynamic. It can be used for Virtual Machine.',
'Class:LogicalInterface/Attribute:virtualmachine_id' => 'Virtual machine',
'Class:LogicalInterface/Attribute:virtualmachine_id+' => '',
'Class:LogicalInterface/Attribute:virtualmachine_name' => 'Virtual machine name',
@@ -1411,7 +1415,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:FiberChannelInterface' => 'Fiber Channel Interface',
'Class:FiberChannelInterface+' => '',
'Class:FiberChannelInterface+' => 'Network Interface to a high-speed network technology primarily used for connecting Storage Systems.',
'Class:FiberChannelInterface/Attribute:speed' => 'Speed',
'Class:FiberChannelInterface/Attribute:speed+' => '',
'Class:FiberChannelInterface/Attribute:topology' => 'Topology',
@@ -1494,7 +1498,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Group' => 'Group',
'Class:Group+' => '',
'Class:Group+' => 'Group is designed to define explicit sets of configurations items for any project purpose. In contrast to Application Solution, a Group is not impacted by any of its component and does not impact them. For example when doing an OS migration, Group can be convenient to gather “Servers to be migrated”. Migrated servers being removed from the group as the migration progresses.',
'Class:Group/ComplementaryName' => '%1$s - %2$s',
'Class:Group/Attribute:name' => 'Name',
'Class:Group/Attribute:name+' => '',
@@ -1515,7 +1519,6 @@ Dict::Add('EN US', 'English', 'English', [
'Class:Group/Attribute:type' => 'Type',
'Class:Group/Attribute:type+' => '',
'Class:Group/Attribute:parent_id' => 'Parent Group',
'Class:Group/Attribute:parent_id+' => '',
'Class:Group/Attribute:parent_name' => 'Name',
'Class:Group/Attribute:parent_name+' => '',
@@ -1629,15 +1632,4 @@ Dict::Add('EN US', 'English', 'English', [
'Menu:OSVersion+' => '',
'Menu:Software' => 'Software catalog',
'Menu:Software+' => 'Software catalog',
]);
//
// Class: PhysicalInterface
//
Dict::Add('EN US', 'English', 'English', [
'Class:PhysicalInterface/Attribute:org_id' => 'Org id',
'Class:PhysicalInterface/Attribute:org_id+' => '',
'Class:PhysicalInterface/Attribute:location_id' => 'Location id',
'Class:PhysicalInterface/Attribute:location_id+' => '',
]);
]);

View File

@@ -596,7 +596,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
//
Dict::Add('EN GB', 'British English', 'British English', [
'Class:WebServer' => 'Web server',
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => '',
'Class:WebServer/Attribute:webapp_list' => 'Web applications',
'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server',

View File

@@ -85,7 +85,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:FunctionalCI' => 'CI Fonctionnel',
'Class:FunctionalCI+' => '',
'Class:FunctionalCI+' => 'Classe abstraite regroupant plusieurs types déléments de configuration.',
'Class:FunctionalCI/Attribute:name' => 'Nom',
'Class:FunctionalCI/Attribute:name+' => '',
'Class:FunctionalCI/Attribute:description' => 'Description',
@@ -134,7 +134,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:PhysicalDevice' => 'Matériel physique',
'Class:PhysicalDevice+' => '',
'Class:PhysicalDevice+' => 'Classe abstraite regroupant les types physiques déléments de configuration. Un matériel physique peut être localisé. Il possède généralement une marque et un modèle.',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s',
'Class:PhysicalDevice/Attribute:serialnumber' => 'Numéro de série',
'Class:PhysicalDevice/Attribute:serialnumber+' => '',
@@ -174,7 +174,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Rack' => 'Rack',
'Class:Rack+' => '',
'Class:Rack+' => 'Conteneur physique pour équipements et châssis.',
'Class:Rack/ComplementaryName' => '%1$s - %2$s',
'Class:Rack/Attribute:nb_u' => 'NB Unité',
'Class:Rack/Attribute:nb_u+' => '',
@@ -202,7 +202,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:TelephonyCI' => 'CI Téléphonie',
'Class:TelephonyCI+' => '',
'Class:TelephonyCI+' => 'Classe abstraite regroupant les équipements de téléphonie.',
'Class:TelephonyCI/Attribute:phonenumber' => 'Numéro',
'Class:TelephonyCI/Attribute:phonenumber+' => '',
]);
@@ -213,7 +213,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Phone' => 'Téléphone',
'Class:Phone+' => '',
'Class:Phone+' => 'Équipement individuel. Téléphone filaire classique.',
]);
//
@@ -222,7 +222,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:MobilePhone' => 'Téléphone mobile',
'Class:MobilePhone+' => '',
'Class:MobilePhone+' => 'Équipement individuel. Téléphone portable.',
'Class:MobilePhone/Attribute:imei' => 'IMEI',
'Class:MobilePhone/Attribute:imei+' => '',
'Class:MobilePhone/Attribute:hw_pin' => 'PIN',
@@ -235,7 +235,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:IPPhone' => 'Téléphone IP',
'Class:IPPhone+' => '',
'Class:IPPhone+' => 'Équipement individuel. Équipement physique dédié aux appels téléphoniques, connecté à un réseau.',
]);
//
@@ -244,7 +244,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Tablet' => 'Tablette',
'Class:Tablet+' => '',
'Class:Tablet+' => 'Équipement individuel. Par exemple iPad, Galaxy Note/Tab Nexus, Kindle...',
]);
//
@@ -252,8 +252,8 @@ Dict::Add('FR FR', 'French', 'Français', [
//
Dict::Add('FR FR', 'French', 'Français', [
'Class:ConnectableCI' => 'CI connecté',
'Class:ConnectableCI+' => '',
'Class:ConnectableCI' => 'Matériel connecté',
'Class:ConnectableCI+' => 'Matériel physique pouvant être connecté à un réseau.',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s',
'Class:ConnectableCI/Attribute:networkdevice_list' => 'Equipements réseaux',
'Class:ConnectableCI/Attribute:networkdevice_list+' => 'Tous les équipements réseaux connectés à ce matériel',
@@ -272,8 +272,8 @@ Dict::Add('FR FR', 'French', 'Français', [
//
Dict::Add('FR FR', 'French', 'Français', [
'Class:DatacenterDevice' => 'Matériel Datacenter',
'Class:DatacenterDevice+' => '',
'Class:DatacenterDevice' => 'Matériel de Datacenter',
'Class:DatacenterDevice+' => 'Matériel connecté. Un équipement physique installé dans un datacenter, généralement dans un rack ou un châssis. Il peut sagir de serveurs, de systèmes de stockage, de switchs SAN, de bandothèques, de NAS…',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s',
'Class:DatacenterDevice/Attribute:rack_id' => 'Rack',
'Class:DatacenterDevice/Attribute:rack_id+' => '',
@@ -317,7 +317,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:NetworkDevice' => 'Equipement réseau',
'Class:NetworkDevice+' => '',
'Class:NetworkDevice+' => 'Matériel connecté et rackable. Tout type déquipement réseau : routeur, switch, hub, load balancer, firewall…',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s',
'Class:NetworkDevice/Attribute:networkdevicetype_id' => 'Type',
'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '',
@@ -339,7 +339,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Server' => 'Serveur',
'Class:Server+' => '',
'Class:Server+' => 'Matériel connecté et rackable qui fournit des ressources de calcul, de stockage ou de connectivité. Il tourne sous une Version d\'OS et héberge des Applications Logicielles.',
'Class:Server/ComplementaryName' => '%1$s - %2$s',
'Class:Server/Attribute:osfamily_id' => 'Famille OS',
'Class:Server/Attribute:osfamily_id+' => '',
@@ -385,7 +385,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:SANSwitch' => 'Switch SAN',
'Class:SANSwitch+' => '',
'Class:SANSwitch+' => 'Matériel connecté et rackable. C\'est un switch utilisé par les réseaux de stockage (Storage Area Network). Il support le protocole Fibre Channel.',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s',
'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Matériels connectés',
'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'Tous les matériels connectés à ce switch SAN',
@@ -397,7 +397,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:TapeLibrary' => 'Bandothèque',
'Class:TapeLibrary+' => '',
'Class:TapeLibrary+' => 'Matériel connecté et rackable hébergeant plusieurs bandes magnétiques (ou cartouches). Utilisé pour la sauvegarde ou larchivage.',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s',
'Class:TapeLibrary/Attribute:tapes_list' => 'Bandes',
'Class:TapeLibrary/Attribute:tapes_list+' => 'Toutes les bandes dans cette bandothèque',
@@ -415,7 +415,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:NAS' => 'NAS',
'Class:NAS+' => '',
'Class:NAS+' => 'Matériel connecté et rackable fournissant un stockage de haute capacité. Dans '.ITOP_APPLICATION_SHORT.', un NAS (Network-attached storage) est lié à des systèmes de fichiers NAS.',
'Class:NAS/ComplementaryName' => '%1$s - %2$s',
'Class:NAS/Attribute:nasfilesystem_list' => 'Systèmes de fichier NAS',
'Class:NAS/Attribute:nasfilesystem_list+' => 'Tous les systèmes de fichier dans ce NAS',
@@ -433,7 +433,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:PC' => 'PC',
'Class:PC+' => '',
'Class:PC+' => 'CI connectable. Un ordinateur personnel (PC) est un matériel physique, de bureau ou portable, tournant avec une version d\'OS et conçu pour exécuter des instances logicielles.',
'Class:PC/ComplementaryName' => '%1$s - %2$s',
'Class:PC/Attribute:osfamily_id' => 'Famille OS',
'Class:PC/Attribute:osfamily_id+' => '',
@@ -461,7 +461,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Printer' => 'Imprimante',
'Class:Printer+' => '',
'Class:Printer+' => 'Connectable CI. Physical Device connected either to the network or to a PC.',
'Class:Printer/ComplementaryName' => '%1$s - %2$s',
]);
@@ -551,7 +551,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:ApplicationSolution' => 'Solution applicative',
'Class:ApplicationSolution+' => '',
'Class:ApplicationSolution+' => 'Les solutions applicatives décrivent des applications complexes composées de plusieurs composants de base. Linformation principale est la liste de ses relations.',
'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs',
'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'Tous les éléments de configuration qui composent cette solution applicative',
'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Processus métiers',
@@ -563,7 +563,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:ApplicationSolution/Attribute:status/Value:inactive' => 'Inactif',
'Class:ApplicationSolution/Attribute:status/Value:inactive+' => '',
'Class:ApplicationSolution/Attribute:redundancy' => 'Analyse d\'impact : configuration de la redondance',
'Class:ApplicationSolution/Attribute:redundancy/disabled' => 'La solution est opérationelle si tous les CIs qui la composent sont opérationnels',
'Class:ApplicationSolution/Attribute:redundancy/disabled' => 'La solution est opérationnelle si tous les CIs qui la composent sont opérationnels',
'Class:ApplicationSolution/Attribute:redundancy/count' => 'Nombre minimal de CIs pour que la solution soit opérationnelle : %1$s',
'Class:ApplicationSolution/Attribute:redundancy/percent' => 'Pourcentage minimal de CIs pour que la solution soit opérationnelle : %1$s %%',
]);
@@ -574,7 +574,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:BusinessProcess' => 'Processus métier',
'Class:BusinessProcess+' => '',
'Class:BusinessProcess+' => 'Un processus métier sert à documenter un processus de haut niveau ou une application importante pour les opérations. Similaire à une solution applicative mais pour des applications ou processus dorganisation de plus haut niveau.',
'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Solutions applicatives',
'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'Toutes les solutions applicatives qui impactent ce processus métier',
'Class:BusinessProcess/Attribute:applicationsolutions_list/UI:Links:Add:Button+' => 'Ajouter une %4$s',
@@ -595,7 +595,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:SoftwareInstance' => 'Instance logiciel',
'Class:SoftwareInstance+' => '',
'Class:SoftwareInstance+' => 'Classe abstraite représentant le déploiement dun logiciel sur un équipement (serveur, PC, machine virtuelle). Dans iTop, il existe différents types dinstances logicielles.',
'Class:SoftwareInstance/Attribute:system_id' => 'Système',
'Class:SoftwareInstance/Attribute:system_id+' => '',
'Class:SoftwareInstance/Attribute:system_name' => 'Nom du système',
@@ -675,7 +675,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:PCSoftware' => 'Logiciel PC',
'Class:PCSoftware+' => 'Application logicielle sur PC',
'Class:PCSoftware+' => 'Instance logicielle pour des logiciels (ex : MS Office, Photoshop, Filezilla) installés sur un PC.',
]);
//
@@ -707,7 +707,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:DatabaseSchema' => 'Instance de base de données',
'Class:DatabaseSchema+' => '',
'Class:DatabaseSchema+' => 'CI fonctionnel. Instance de base de données fonctionnant sur un serveur de BDD spécifique.',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s',
'Class:DatabaseSchema/Attribute:dbserver_id' => 'Serveur de base de données',
'Class:DatabaseSchema/Attribute:dbserver_id+' => '',
@@ -721,7 +721,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:WebApplication' => 'Application Web',
'Class:WebApplication+' => '',
'Class:WebApplication+' => 'CI fonctionnel. Instance dune application accessible via un navigateur web et sexécutant sur un serveur web donné.',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s',
'Class:WebApplication/Attribute:webserver_id' => 'Serveur Web',
'Class:WebApplication/Attribute:webserver_id+' => '',
@@ -737,7 +737,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:VirtualDevice' => 'Equipement Virtuel',
'Class:VirtualDevice+' => '',
'Class:VirtualDevice+' => 'CI fonctionnel. Classe abstraite utilisée pour la virtualisation de serveurs.',
'Class:VirtualDevice/Attribute:status' => 'Etat',
'Class:VirtualDevice/Attribute:status+' => '',
'Class:VirtualDevice/Attribute:status/Value:implementation' => 'Implémentation',
@@ -758,7 +758,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:VirtualHost' => 'Hôte Virtuel',
'Class:VirtualHost+' => '',
'Class:VirtualHost+' => 'Équipement virtuel. Classe abstraite pour les équipements hébergeant des machines virtuelles.',
'Class:VirtualHost/Attribute:virtualmachine_list' => 'Machines virtuelles',
'Class:VirtualHost/Attribute:virtualmachine_list+' => 'Toutes les machiens virtuelles hébergées par cet hôte',
'Class:VirtualHost/Attribute:virtualmachine_list/UI:Links:Create:Button+' => 'Créer une %4$s',
@@ -853,7 +853,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:LogicalVolume' => 'Volume logique',
'Class:LogicalVolume+' => '',
'Class:LogicalVolume+' => 'Unité de stockage gérée à lintérieur dun système de stockage.',
'Class:LogicalVolume/Attribute:name' => 'Nom',
'Class:LogicalVolume/Attribute:name+' => '',
'Class:LogicalVolume/Attribute:lun_id' => 'LUN ID',
@@ -982,7 +982,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Software' => 'Logiciel',
'Class:Software+' => '',
'Class:Software+' => 'Un logiciel est un élément générique du catalogue logiciel. Il possède une version particulière. Dans iTop, un logiciel appartient à une catégorie : serveur de BDD, middleware, logiciel PC, serveur web ou autre.',
'Class:Software/ComplementaryName' => '%1$s - %2$s',
'Class:Software/Attribute:name' => 'Nom',
'Class:Software/Attribute:name+' => '',
@@ -1128,7 +1128,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:OSLicence' => 'Licence OS',
'Class:OSLicence+' => '',
'Class:OSLicence+' => 'Contrat de licence pour un système dexploitation particulier.',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s',
'Class:OSLicence/Attribute:osversion_id' => 'Version OS',
'Class:OSLicence/Attribute:osversion_id+' => '',
@@ -1158,7 +1158,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:SoftwareLicence' => 'Licence Logiciel',
'Class:SoftwareLicence+' => '',
'Class:SoftwareLicence+' => 'Contrat de licence pour un logiciel particulier.',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s',
'Class:SoftwareLicence/Attribute:software_id' => 'Logiciel',
'Class:SoftwareLicence/Attribute:software_id+' => '',
@@ -1240,8 +1240,8 @@ Dict::Add('FR FR', 'French', 'Français', [
//
Dict::Add('FR FR', 'French', 'Français', [
'Class:Model' => 'Modèle',
'Class:Model+' => '',
'Class:Model' => 'Modèle de matériel',
'Class:Model+' => 'Typologie. Liste des valeurs possibles pour le modèle dun matériel physique.',
'Class:Model/ComplementaryName' => '%1$s - %2$s',
'Class:Model/Attribute:brand_id' => 'Marque',
'Class:Model/Attribute:brand_id+' => '',
@@ -1305,7 +1305,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:NetworkDeviceType' => 'Type d\'équipement réseau',
'Class:NetworkDeviceType+' => '',
'Class:NetworkDeviceType+' => 'Typologie. Valeurs possibles pour le type dun équipement réseau (ex : routeur, switch, firewall, etc.).',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Equipements réseaux',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'Tous les équipements réseaux correspondant à ce type',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list/UI:Links:Create:Button+' => 'Créer un %4$s',
@@ -1322,7 +1322,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:IOSVersion' => 'Version IOS',
'Class:IOSVersion+' => '',
'Class:IOSVersion+' => 'Typologie. Valeurs possibles pour les types de systèmes dexploitation pour équipements réseau.',
'Class:IOSVersion/Attribute:brand_id' => 'Marque',
'Class:IOSVersion/Attribute:brand_id+' => '',
'Class:IOSVersion/Attribute:brand_name' => 'Nom Marque',
@@ -1490,7 +1490,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:IPInterface' => 'Interface IP',
'Class:IPInterface+' => '',
'Class:IPInterface+' => 'Classe abstraite. Type dinterface réseau avec une adresse IP.',
'Class:IPInterface/Attribute:ipaddress' => 'Adresse IP',
'Class:IPInterface/Attribute:ipaddress+' => '',
'Class:IPInterface/Attribute:macaddress' => 'Adresse MAC',
@@ -1511,7 +1511,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:PhysicalInterface' => 'Interface physique',
'Class:PhysicalInterface+' => '',
'Class:PhysicalInterface+' => 'Type dinterface IP représentant une interface réseau physique (ex : carte Ethernet).',
'Class:PhysicalInterface/Name' => '%2$s %1$s',
'Class:PhysicalInterface/Attribute:connectableci_id' => 'Matériel',
'Class:PhysicalInterface/Attribute:connectableci_id+' => '',
@@ -1562,7 +1562,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:FiberChannelInterface' => 'Interface Fibre',
'Class:FiberChannelInterface+' => '',
'Class:FiberChannelInterface+' => 'Interface réseau vers une technologie haut débit principalement utilisée pour connecter des systèmes de stockage.',
'Class:FiberChannelInterface/Attribute:speed' => 'Vitesse',
'Class:FiberChannelInterface/Attribute:speed+' => '',
'Class:FiberChannelInterface/Attribute:topology' => 'Topologie',

View File

@@ -577,7 +577,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
//
Dict::Add('IT IT', 'Italian', 'Italiano', [
'Class:WebServer' => 'Web server',
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => '~~',
'Class:WebServer/Attribute:webapp_list' => 'Applicazioni web',
'Class:WebServer/Attribute:webapp_list+' => 'Tutte le applicazioni web disponibili su questo server web',

View File

@@ -577,7 +577,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
//
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:WebServer' => 'Web server',
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => '~~',
'Class:WebServer/Attribute:webapp_list' => 'Webové aplikácie',
'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~',

View File

@@ -19,7 +19,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:FAQ/Attribute:summary+' => '',
'Class:FAQ/Attribute:description' => 'Description',
'Class:FAQ/Attribute:description+' => '',
'Class:FAQ/Attribute:category_id' => 'Categorie',
'Class:FAQ/Attribute:category_id' => 'Catégorie',
'Class:FAQ/Attribute:category_id+' => '',
'Class:FAQ/Attribute:category_name' => 'Nom catégorie',
'Class:FAQ/Attribute:category_name+' => '',

View File

@@ -53,7 +53,7 @@
Dict::Add('EN US', 'English', 'English', [
'Class:KnownError' => 'Known Error',
'Class:KnownError+' => 'Error documented for a known issue',
'Class:KnownError+' => 'Error with multiple occurrences, documented to ease troubleshooting.',
'Class:KnownError/Attribute:name' => 'Name',
'Class:KnownError/Attribute:name+' => 'This is expected to be a unique identifier within the Known Errors of this organization',
'Class:KnownError/Attribute:org_id' => 'Organization',
@@ -61,7 +61,7 @@ Dict::Add('EN US', 'English', 'English', [
'Class:KnownError/Attribute:cust_name' => 'Organization Name',
'Class:KnownError/Attribute:cust_name+' => '',
'Class:KnownError/Attribute:problem_id' => 'Related Problem',
'Class:KnownError/Attribute:problem_id+' => 'The problem which couldn\'t be solved immediately and has led to the creation of this known error',
'Class:KnownError/Attribute:problem_id+' => 'The problem which could\'nt be solved immediately and has led to the creation of this known error',
'Class:KnownError/Attribute:problem_ref' => 'Related Problem Ref',
'Class:KnownError/Attribute:problem_ref+' => '',
'Class:KnownError/Attribute:symptom' => 'Symptom',

View File

@@ -77,7 +77,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Problem' => 'Problem',
'Class:Problem+' => '',
'Class:Problem+' => 'An incident becomes a Problem when it is not resolved in a timely manner or when it recurs frequently',
'Class:Problem/Attribute:status' => 'Status',
'Class:Problem/Attribute:status+' => '',
'Class:Problem/Attribute:status/Value:new' => 'New',

View File

@@ -238,6 +238,11 @@
<action id="action:bulk delete">allow</action>
</actions>
</group>
<group id="Ticketing">
<actions>
<action id="stimulus:ev_close">allow</action>
</actions>
</group>
<group id="UserRequest">
<actions>
<action id="stimulus:ev_approve">allow</action>

View File

@@ -307,7 +307,9 @@
</field>
<field id="servicesubcategory_id" xsi:type="AttributeExternalKey">
<filter><![CDATA[SELECT ServiceSubcategory WHERE service_id = :this->service_id AND status != 'obsolete']]></filter>
<dependencies/>
<dependencies>
<attribute id="service_id"/>
</dependencies>
<sql>servicesubcategory_id</sql>
<target_class>ServiceSubcategory</target_class>
<is_null_allowed>true</is_null_allowed>

View File

@@ -243,7 +243,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:Service/Attribute:description' => 'Popis',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Dokumenty',

View File

@@ -242,7 +242,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:Service/Attribute:description' => 'Beskrivelse',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Dokument',
@@ -500,7 +500,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -242,7 +242,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:Service/Attribute:description' => 'Beschreibung',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Dokumente',

View File

@@ -268,7 +268,7 @@ Dict::Add('EN US', 'English', 'English', [
'Class:Service/Attribute:description' => 'Description',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Documents',
@@ -526,7 +526,7 @@ Dict::Add('EN US', 'English', 'English', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
]);

View File

@@ -268,7 +268,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
'Class:Service/Attribute:description' => 'Description',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Documents',
@@ -526,7 +526,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
]);

View File

@@ -239,7 +239,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'Class:Service/Attribute:description' => 'Descripción',
'Class:Service/Attribute:description+' => 'Descripción',
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
'Class:Service/Attribute:documents_list' => 'Documentos',

View File

@@ -247,7 +247,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:Service/Attribute:description' => 'Description',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Documents',
@@ -511,7 +511,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',

View File

@@ -241,7 +241,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'Class:Service/Attribute:description' => 'Leírás',
'Class:Service/Attribute:description+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:documents_list' => 'Dokumentumok',

View File

@@ -241,7 +241,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
'Class:Service/Attribute:description' => 'Descrizione',
'Class:Service/Attribute:description+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:documents_list' => 'Documenti',

View File

@@ -241,7 +241,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:Service/Attribute:description' => '説明',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => '文書',
@@ -499,7 +499,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:DeliveryModel/Attribute:description' => '説明',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -243,7 +243,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'Class:Service/Attribute:description' => 'Omschrijving',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Documenten',

View File

@@ -241,7 +241,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
'Class:Service/Attribute:description' => 'Opis',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Dokumenty',

View File

@@ -241,7 +241,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'Class:Service/Attribute:description' => 'Descrição',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Documentos',

View File

@@ -242,7 +242,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
'Class:Service/Attribute:description' => 'Описание',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => 'Документы',

View File

@@ -241,7 +241,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:Service/Attribute:description' => 'Popis',
'Class:Service/Attribute:description+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:documents_list' => 'Dokumenty',
@@ -499,7 +499,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:DeliveryModel/Attribute:description' => 'Popis',
'Class:DeliveryModel/Attribute:description+' => '~~',
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -241,7 +241,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'Class:Service/Attribute:description' => 'Tanımlama',
'Class:Service/Attribute:description+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Service Family~~',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name~~',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:documents_list' => 'Documents~~',
@@ -499,7 +499,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'Class:DeliveryModel/Attribute:description' => 'Description~~',
'Class:DeliveryModel/Attribute:description+' => '~~',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => 'Customers~~',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -264,7 +264,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
'Class:Service/Attribute:description' => '描述',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:servicefamily_id' => '服务系列',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:documents_list' => '文档',

View File

@@ -218,7 +218,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:Service/Attribute:organization_name' => 'Název poskytovatele',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Popis',

View File

@@ -217,7 +217,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:Service/Attribute:organization_name' => 'Leverandør navn',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Beskrivelse',
@@ -463,7 +463,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -217,7 +217,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:Service/Attribute:organization_name' => 'Provider-Name',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Beschreibung',

View File

@@ -240,7 +240,7 @@ Dict::Add('EN US', 'English', 'English', [
'Class:Service/Attribute:organization_name' => 'Provider Name',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Description',
@@ -486,7 +486,7 @@ Dict::Add('EN US', 'English', 'English', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
]);

View File

@@ -240,7 +240,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
'Class:Service/Attribute:organization_name' => 'Provider Name',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Description',
@@ -486,7 +486,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
]);

View File

@@ -214,7 +214,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'Class:Service/Attribute:organization_name' => 'Proveedor',
'Class:Service/Attribute:organization_name+' => 'Proveedor',
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
'Class:Service/Attribute:description' => 'Descripción',

View File

@@ -214,7 +214,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:Service/Attribute:organization_name' => 'Nom fournisseur',
'Class:Service/Attribute:organization_name+' => 'Nom commun',
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:services_list/UI:Links:Create:Button+' => 'Créer un %4$s',
@@ -478,7 +478,7 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:DeliveryModel/Attribute:description' => 'Description',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',

View File

@@ -216,7 +216,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'Class:Service/Attribute:organization_name' => 'Szolgáltató név',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Leírás',

View File

@@ -215,7 +215,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
'Class:Service/Attribute:organization_name' => 'Nome del Fornitore',
'Class:Service/Attribute:organization_name+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:description' => 'Descrizione',

View File

@@ -215,7 +215,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:Service/Attribute:organization_name' => 'プロバイダー名',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => '説明',
@@ -461,7 +461,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:DeliveryModel/Attribute:description' => '説明',
'Class:DeliveryModel/Attribute:description+' => '',
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -217,7 +217,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'Class:Service/Attribute:organization_name' => 'Naam leverancier',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Omschrijving',

View File

@@ -215,7 +215,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
'Class:Service/Attribute:organization_name' => 'Nazwa dostawcy',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Opis',

View File

@@ -215,7 +215,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'Class:Service/Attribute:organization_name' => 'Nome do provedor',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Descrição',

View File

@@ -216,7 +216,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
'Class:Service/Attribute:organization_name' => 'Поставщик',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Описание',

View File

@@ -215,7 +215,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:Service/Attribute:organization_name' => 'Meno poskytovateľa',
'Class:Service/Attribute:organization_name+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:description' => 'Popis',
@@ -461,7 +461,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:DeliveryModel/Attribute:description' => 'Popis',
'Class:DeliveryModel/Attribute:description+' => '~~',
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
]);

View File

@@ -216,7 +216,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'Class:Service/Attribute:organization_name' => 'Sağlayıcı Adı',
'Class:Service/Attribute:organization_name+' => '~~',
'Class:Service/Attribute:servicefamily_id' => 'Servis Ailesi',
'Class:Service/Attribute:servicefamily_id+' => '~~',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => 'Servis Aile Adı',
'Class:Service/Attribute:servicefamily_name+' => '~~',
'Class:Service/Attribute:description' => 'Tanımlama',

View File

@@ -236,7 +236,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
'Class:Service/Attribute:organization_name' => '供应商名称',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => '服务系列',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => '描述',

File diff suppressed because one or more lines are too long

View File

@@ -48,7 +48,7 @@
Dict::Add('EN US', 'English', 'English', [
'Class:Organization' => 'Organization',
'Class:Organization+' => '',
'Class:Organization+' => 'It can be a customer, a provider, your company or departments within your company. Organizations can be structured hierarchically. Users can be limited to objects belonging to some organizations only.',
'Class:Organization/Attribute:name' => 'Name',
'Class:Organization/Attribute:name+' => 'Common name',
'Class:Organization/Attribute:code' => 'Code',
@@ -114,7 +114,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Contact' => 'Contact',
'Class:Contact+' => '',
'Class:Contact+' => 'Abstract class. A Contact can be linked to Tickets and FunctionalCIs for different purposes, such as incident dispatching and notifications.',
'Class:Contact/ComplementaryName' => '%1$s - %2$s',
'Class:Contact/Attribute:name' => 'Name',
'Class:Contact/Attribute:name+' => '',
@@ -152,7 +152,8 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Person' => 'Person',
'Class:Person+' => '',
'Class:Person+' => 'A type of Contact used to describe physical persons. Persons can be grouped into Teams. Persons can be linked to other configuration items (eg. to describe who to contact in case of incident with an application).
Other usage: the caller of a User request is a Person as well as the agent assigned to resolve it.',
'Class:Person/ComplementaryName' => '%1$s - %2$s',
'Class:Person/Attribute:name' => 'Last Name',
'Class:Person/Attribute:name+' => '',
@@ -193,7 +194,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Team' => 'Team',
'Class:Team+' => '',
'Class:Team+' => 'A type of Contact. Often used to group Persons, but not only. Teams are expected to watch Tickets dispatched to them, and assign it to an agent, usually a member of that team.',
'Class:Team/ComplementaryName' => '%1$s - %2$s',
'Class:Team/Attribute:persons_list' => 'Members',
'Class:Team/Attribute:persons_list+' => 'All the people belonging to this team',
@@ -214,7 +215,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Document' => 'Document',
'Class:Document+' => '',
'Class:Document+' => 'Abstract class. - A document that can be shared across multiple objects, making it easy and quick to retrieve from all relevant locations.',
'Class:Document/ComplementaryName' => '%1$s - %2$s - %3$s',
'Class:Document/Attribute:name' => 'Name',
'Class:Document/Attribute:name+' => '',
@@ -250,7 +251,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DocumentFile' => 'Document File',
'Class:DocumentFile+' => '',
'Class:DocumentFile+' => 'It\'s a type of Document which includes an uploaded file (in any format: Word, PDF, Spreadsheet, etc.).',
'Class:DocumentFile/Attribute:file' => 'File',
'Class:DocumentFile/Attribute:file+' => '',
]);
@@ -261,7 +262,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DocumentNote' => 'Document Note',
'Class:DocumentNote+' => '',
'Class:DocumentNote+' => 'Used to store a text document. HTML formatting is supported using the WYSIWYG editor. Search can be performed on its content.',
'Class:DocumentNote/Attribute:text' => 'Text',
'Class:DocumentNote/Attribute:text+' => '',
]);
@@ -272,7 +273,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DocumentWeb' => 'Document Web',
'Class:DocumentWeb+' => '',
'Class:DocumentWeb+' => 'Hyperlinks to external applications or documents, acting as pointers to external resources. You cannot search in their content from '.ITOP_APPLICATION_SHORT,
'Class:DocumentWeb/Attribute:url' => 'URL',
'Class:DocumentWeb/Attribute:url+' => '',
]);
@@ -283,7 +284,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Typology' => 'Typology',
'Class:Typology+' => '',
'Class:Typology+' => 'Abstract class. ExternalKeyAttribute to a Typology subclass are used in place of an EnumAttribute, to have more dynamic values.',
'Class:Typology/Attribute:name' => 'Name',
'Class:Typology/Attribute:name+' => '',
'Class:Typology/Attribute:finalclass' => 'Typology sub-class',
@@ -296,7 +297,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:DocumentType' => 'Document Type',
'Class:DocumentType+' => '',
'Class:DocumentType+' => 'Typology. A classification system used to organize and logically group documents',
]);
//
@@ -305,7 +306,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:ContactType' => 'Contact Type',
'Class:ContactType+' => '',
'Class:ContactType+' => 'Typology to organize your Contacts and group them logically for you.',
]);
//

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<QueryOQL alias="QueryOQL" id="8">
<name>L'agent du ticket</name>
<name>L'agent du Ticket</name>
<description>Utilisable dans les notifications, pour informer l'agent en charge du ticket.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
@@ -9,9 +9,8 @@
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="4">
<name>L'agent du ticket s'il n'a pas déclenché la notification</name>
<description>Utilisable dans les notifications, pour informer l'agent en charge du ticket, sauf si c'est l'agent lui-même qui déclenche la notification
</description>
<name>L'agent du Ticket s'il n'a pas déclenché la notification</name>
<description>Utilisable dans les notifications, pour informer l'agent en charge du ticket, sauf si c'est l'agent lui-même qui déclenche la notification.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
<fields>id,email</fields>
@@ -19,7 +18,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="3">
<name>Le demandeur et les contacts liés au Ticket</name>
<description>Utilisable dans les notifications, pour informer le demandeur ainsi que tout les contacts liés au ticket</description>
<description>Utilisable dans les notifications, pour informer le demandeur ainsi que tous les contacts liés au ticket.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id
UNION SELECT Person WHERE id=:this->caller_id
@@ -29,7 +28,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="1">
<name>Le demandeur du Ticket</name>
<description>Utilisable dans les notifications, pour informer le demandeur du ticket</description>
<description>Utilisable dans les notifications, pour informer le demandeur du ticket.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
<fields>id,email</fields>
@@ -37,7 +36,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="2">
<name>Les contacts liés au Ticket</name>
<description>Utilisable dans les notifications, pour informer tout les contacts liés au ticket</description>
<description>Utilisable dans les notifications, pour informer tous les contacts liés au ticket.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
<fields>id,email</fields>
@@ -45,7 +44,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="7">
<name>Le manager du demandeur</name>
<description>Utilisable dans les notifications, pour informer le manager du demandeur d'un Ticket</description>
<description>Utilisable dans les notifications, pour informer le manager du demandeur d'un ticket.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
<fields>id,email</fields>
@@ -54,7 +53,7 @@
<QueryOQL alias="QueryOQL" id="9">
<name>La personne qui a déclenché la notification</name>
<description>Utilisable dans les notifications, pour informer la personne qui a effectué l'action qui a provoqué la notification.
Utilisée seule, cette requête retourne la personne liée à l'utilisateur iTop qui l'execute.
Utilisée seule, cette requête retourne la personne liée à l'utilisateur iTop qui l'exécute.
</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
@@ -74,7 +73,7 @@
<QueryOQL alias="QueryOQL" id="5">
<name>Les membres de l'équipe hors l'agent</name>
<description>Utilisable dans les notifications, pour informer les membres de l'équipe en charge du ticket.
L'agent lui-même est exclus de cette liste.
L'agent lui-même est exclu de cette liste.
</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
@@ -103,7 +102,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="12">
<name>Les contacts d'un Service</name>
<description>Utilisable dans les notifications, pour informer les contacts liés au Service courant.</description>
<description>Utilisable dans les notifications, pour informer les contacts liés au service courant.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToService AS L ON L.contact_id=C.id
WHERE L.service_id = :this->id
@@ -113,7 +112,7 @@
</QueryOQL>
<QueryOQL alias="QueryOQL" id="13">
<name>Les contacts d'un Contrat</name>
<description>Utilisable dans les notifications, pour informer les contacts liés au Contrat courant.</description>
<description>Utilisable dans les notifications, pour informer les contacts liés au contrat courant.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToContract AS L ON L.contact_id=C.id
WHERE L.contract_id = :this->id

View File

@@ -12,8 +12,7 @@ SetupWebPage::AddModule(
// Setup
//
'dependencies' => [
'itop-structure/2.7.1',
'itop-portal/3.0.0', // module_design_itop_design->module_designs->itop-portal
'itop-structure/2.7.1 || itop-portal/3.0.0', // itop-portal : module_design_itop_design->module_designs->itop-portal
],
'mandatory' => false,
'visible' => true,

View File

@@ -708,6 +708,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'Class:TriggerOnObjectUpdate' => 'Triger \'aktualizace objektu\'',
'Class:TriggerOnObjectUpdate+' => 'Spustit při aktualizaci objektu [podřízené třídy] dané třídy',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Cílová pole',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -707,6 +707,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
Dict::Add('DA DA', 'Danish', 'Dansk', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -704,6 +704,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:TriggerOnObjectUpdate' => 'Trigger (bei Objektanpassung)',
'Class:TriggerOnObjectUpdate+' => 'Trigger bei Objektanpassung einer gegebenen Klasse oder Kindklasse',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Ziel-Felder',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -801,6 +801,7 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

File diff suppressed because it is too large Load Diff

View File

@@ -784,6 +784,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
Dict::Add('EN GB', 'British English', 'British English', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -695,6 +695,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'Class:TriggerOnObjectUpdate' => 'Disparador (actualizando un objecto)',
'Class:TriggerOnObjectUpdate+' => 'Disparador al actualizar un objeto de la clase dada [o una clase hija]',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos objetivo',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Campos que serán monitorizados',
]);

View File

@@ -746,6 +746,7 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:TriggerOnObjectUpdate' => 'Déclencheur sur la modification d\'un objet',
'Class:TriggerOnObjectUpdate+' => '',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'Ce filtre est appliqué après la sauvegarde en base de l\'objet modifié. Il restreint les objets qui vont déclencher les actions.',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Attributs cible',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -702,6 +702,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'Class:TriggerOnObjectUpdate' => 'Eseményindító (objektum frissítéskor)',
'Class:TriggerOnObjectUpdate+' => 'Az adott osztály [egy gyermekosztálya] objektumának frissítésekor elinduló eseményindító',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Célmezők',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -702,6 +702,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
Dict::Add('IT IT', 'Italian', 'Italiano', [
'Class:TriggerOnObjectUpdate' => 'Trigger (alla modifica dell\'oggetto)',
'Class:TriggerOnObjectUpdate+' => 'Trigger alla modifica dell\'oggetto di [una classe figlia della] classe specificata',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campi di destinazione',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -706,6 +706,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
Dict::Add('JA JP', 'Japanese', '日本語', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
]);

View File

@@ -704,6 +704,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'Class:TriggerOnObjectUpdate' => 'Trigger (bij het aanpassen van een object)',
'Class:TriggerOnObjectUpdate+' => 'Trigger bij het aanpassen van een object van de opgegeven klasse (of subklasse ervan)',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Doelvelden',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -704,6 +704,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
Dict::Add('PL PL', 'Polish', 'Polski', [
'Class:TriggerOnObjectUpdate' => 'Wyzwalacz (przy aktualizacji obiektu)',
'Class:TriggerOnObjectUpdate+' => 'Wyzwalanie przy aktualizacji obiektu [klasy potomnej] danej klasy',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Pola docelowe',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -702,6 +702,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'Class:TriggerOnObjectUpdate' => 'Gatilho (na atualização do objeto)',
'Class:TriggerOnObjectUpdate+' => 'Gatilho na atualização de objeto de [uma classe filha] de uma determinada classe',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos de destino',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -707,6 +707,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
Dict::Add('RU RU', 'Russian', 'Русский', [
'Class:TriggerOnObjectUpdate' => 'Триггер на обновление объекта',
'Class:TriggerOnObjectUpdate+' => 'Триггер на обновление объекта данного или дочернего класса',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Отслеживаемые поля',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Поля объекта, при обновлении которых сработает триггер',
]);

View File

@@ -720,6 +720,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
]);

View File

@@ -707,6 +707,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -739,6 +739,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
Dict::Add('ZH CN', 'Chinese', '简体中文', [
'Class:TriggerOnObjectUpdate' => '触发器 (对象更新时)',
'Class:TriggerOnObjectUpdate+' => '指定类型或子类型对象更新时的触发器',
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => '目标字段',
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
]);

View File

@@ -1,17 +0,0 @@
git copy of one file into two files without loosing history
```
git mv foo bar
git commit
SAVED=`git rev-parse HEAD`
git reset --hard HEAD^
git mv foo copy
git commit
git merge $SAVED # This will generate conflicts
git commit -a # Trivially resolved like this
git mv copy foo
git commit
```

View File

@@ -1,19 +1,3 @@
/**
* Image renderer plugin for TomSelect
*/
TomSelect.define('image_renderer', function(options) {
this.settings.render.option = function(data, escape) {
return `<div class="ibo-input-select-icon--menu--item">
<img src="${options['images_resource_path']+escape(data.value)}" alt="${data.text}" />${escape(data.text)}
</div>`;
};
this.settings.render.item = function(data, escape) {
return `<div class="ibo-input-select-icon--menu--item">
<img src="${options['images_resource_path']+escape(data.value)}" alt="${data.text}"/>${escape(data.text)}
</div>`;
};
});
class ChoicesElement extends HTMLSelectElement {
// register the custom element
@@ -32,14 +16,6 @@ class ChoicesElement extends HTMLSelectElement {
this.plugins.push('remove_button');
}
// plugins
if(this.hasAttribute('data-plugins')){
const aPlugins = JSON.parse(this.getAttribute('data-plugins'));
Array.from(aPlugins).values().forEach(plugin => {
this.plugins.push(plugin);
});
}
const options = {
plugins: this.plugins,
wrapperClass: 'ts-wrapper ibo-input-wrapper ibo-input-select-wrapper--with-buttons ibo-input-select-autocomplete-wrapper',
@@ -53,7 +29,7 @@ class ChoicesElement extends HTMLSelectElement {
};
if (this.getAttribute('data-tom-select-disable-auto-complete')) {
options.controlInput = null;
// options.controlInput = null;
}
if (this.getAttribute('data-tom-select-max-items-selected') && this.getAttribute('data-tom-select-max-items-selected') !== '') {
options.maxItems = parseInt(this.getAttribute('data-tom-select-max-items-selected'));
@@ -67,4 +43,3 @@ class ChoicesElement extends HTMLSelectElement {
}

View File

@@ -20,8 +20,6 @@ class TurboStreamEvent extends HTMLElement {
},
});
console.log(event);
document.dispatchEvent(event);
}

View File

@@ -1,83 +0,0 @@
class IboGridSlot extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
/** @type {string} unique cell id */
this.id = '';
/** @type {number} */
this.iPosX = this.getAttribute('gs-x') ? parseInt(this.getAttribute('gs-x'), 10) : 0;
/** @type {number} */
this.iPostY = this.getAttribute('gs-y') ? parseInt(this.getAttribute('gs-y'), 10) : 0;
/** @type {number} */
this.iWidth = this.getAttribute('gs-w') ? parseInt(this.getAttribute('gs-w'), 10) : 1;
/** @type {number} */
this.iHeight = this.getAttribute('gs-h') ? parseInt(this.getAttribute('gs-h'), 10) : 1;
/** @type {IboDashlet|null} contained dashlet id */
this.sDashletId = null;
/** @type {IboDashlet|null} contained dashlet element */
this.oDashlet = this.querySelector('ibo-dashlet') || null;
/** @type {Object} freeform metadata */
this.meta = {};
}
static MakeNew(oDashletElem, aOptions = {}) {
const oSlot = document.createElement('ibo-dashboard-grid-slot');
oDashletElem.classList.add("grid-stack-item-content");
oSlot.appendChild(oDashletElem);
oSlot.classList.add("grid-stack-item");
oSlot.oDashlet = oDashletElem;
return oSlot;
}
Serialize(bIncludeHtml = false) {
const oDashlet = this.oDashlet;
const aSlotData = {
position_x: this.iPosX,
position_y: this.iPostY,
width: this.iWidth,
height: this.iHeight
};
const aDashletData = oDashlet ? oDashlet.Serialize(bIncludeHtml) : {};
return {
...aSlotData,
dashlet: {...aDashletData}
};
}
static observedAttributes = ['gs-x', 'gs-y', 'gs-w', 'gs-h'];
attributeChangedCallback(name, oldValue, newValue) {
switch (name) {
case 'gs-x':
this.iPosX = parseInt(newValue, 10) || 0;
break;
case 'gs-y':
this.iPostY = parseInt(newValue, 10) || 0;
break;
case 'gs-w':
this.iWidth = parseInt(newValue, 10) || 1;
break;
case 'gs-h':
this.iHeight = parseInt(newValue, 10) || 1;
break;
}
}
}
customElements.define('ibo-dashboard-grid-slot', IboGridSlot);

View File

@@ -1,161 +0,0 @@
class IboGrid extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
/** @type {number} */
this.columnsCount = 12;
/** @type {boolean} unused yet*/
this.bEditable = false;
/** @type {GridStack|null} GridStack instance */
this.oGrid = null;
/** @type {Array<IboGridSlot>} */
this.aSlots = [];
this.SetupGrid();
}
SetupGrid() {
let aCandidateSlots = Array.from(this.querySelectorAll('ibo-dashboard-grid-slot'));
aCandidateSlots.forEach(oSlot => {
const aAttrs = ['gs-x', 'gs-y', 'gs-w', 'gs-h', 'id'];
aAttrs.forEach(sAttr => {
const sVal = oSlot.getAttribute(sAttr) || oSlot.getAttribute('data-'+sAttr);
if (sVal !== null) {
oSlot.setAttribute(sAttr, sVal);
}
});
});
this.oGrid = GridStack.init({
column: this.columnsCount,
marginTop: 8,
marginLeft: 8,
marginRight: 0,
marginBottom: 0,
resizable: {handles: 'all'},
disableDrag: true,
disableResize: true,
float: true
}, this);
}
getSlots() {
return this.oGrid.getGridItems();
}
SetEditable(bIsEditable) {
this.bEditable = bIsEditable;
if (this.oGrid !== null) {
this.oGrid.enableMove(bIsEditable);
this.oGrid.enableResize(bIsEditable);
}
}
GetDashletElement(sDashletId) {
const aSlots = this.getSlots();
for (let oSlot of aSlots) {
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
return oSlot.oDashlet;
}
}
return null;
}
AddDashlet(sDashlet, aOptions = {}) {
// Get the dashlet as an object
const oParser = new DOMParser();
const oDocument = oParser.parseFromString(sDashlet, 'text/html');
const oDashlet = oDocument.body.firstChild;
const oSlot = IboGridSlot.MakeNew(oDashlet);
this.append(oSlot);
let aDefaultOptions = {
autoPosition: !(aOptions.hasOwnProperty('x') || aOptions.hasOwnProperty('y')),
}
this.oGrid.makeWidget(oSlot, Object.assign(aDefaultOptions, aOptions));
return oDashlet.sDashletId;
}
RefreshDashlet (sDashlet, aOptions = {}) {
const oParser = new DOMParser();
const oDocument = oParser.parseFromString(sDashlet, 'text/html');
const oNewDashlet = oDocument.body.firstElementChild;
// Can't use oNewDashet.sDashletId as it's not in the DOM yet and connectedCallback hasn't been called yet
const oExistingDashlet = this.GetDashletElement(oNewDashlet.getAttribute('data-dashlet-id') );
// Copy attributes
for (const sAttr of oNewDashlet.attributes) {
oExistingDashlet.setAttribute(sAttr.name, sAttr.value);
}
// If we refresh a dashlet, its parent slot remains the same, we just need to update its content
let oSlotForExistingDashlet = null;
const aSlots = this.getSlots();
for (let oSlot of aSlots) {
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === oNewDashlet.getAttribute('data-dashlet-id')) {
oSlotForExistingDashlet = oSlot;
break;
}
}
// There must be a slot for the existing dashlet
if(oSlotForExistingDashlet !== null) {
this.oGrid.removeWidget(oSlotForExistingDashlet);
oSlotForExistingDashlet.innerHTML = oNewDashlet.outerHTML;
this.oGrid.makeWidget(oSlotForExistingDashlet);
}
}
CloneDashlet(sDashletId) {
const aSlots = this.getSlots();
for (let oSlot of aSlots) {
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
const sWidth = oSlot.iWidth;
const sHeight = oSlot.iHeight;
// Ask a new rendered dashlet to avoid duplicating IDs
// Still we'll copy width and height
this.closest('ibo-dashboard')?.AddNewDashlet(oSlot.oDashlet.sType, oSlot.oDashlet.formData, {
'w': sWidth,
'h': sHeight
});
break;
}
}
}
RemoveDashlet(sDashletId) {
const aSlots = this.getSlots();
for (let oSlot of aSlots) {
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
this.oGrid.removeWidget(oSlot);
break;
}
}
}
ClearGrid() {
this.oGrid.removeAll();
}
Serialize(bIncludeHtml = false) {
const aSlots = this.getSlots();
return aSlots.reduce((aAccumulator, oSlot) => {
aAccumulator[oSlot.oDashlet.sDashletId] = oSlot.Serialize(bIncludeHtml);
return aAccumulator;
}, {});
}
}
customElements.define('ibo-dashboard-grid', IboGrid);

View File

@@ -1,371 +0,0 @@
class IboDashboard extends HTMLElement {
constructor() {
super();
/** @type {string} */
this.sId = "";
/** @type {string} */
this.sTitle = "";
/** @type {boolean} unused yet */
this.isEditable = false;
/** @type {boolean} */
this.bEditMode = false;
/** @type {boolean} unused yet */
this.bAutoRefresh = false;
/** @type {number} unused yet */
this.iRefreshRate = 0;
/** @type {IboGrid|null} */
this.oGrid = null;
/** @type {string|null} unused yet */
this.refreshUrl = null;
/** @type {string|null} unused yet */
this.csrfToken = null;
/** @type {number} Payload schema version */
this.schemaVersion = 2;
/** @type {object|null} Last saved state for cancel functionality, unused yet */
this.aLastSavedState = null;
}
connectedCallback() {
this.sId = this.getAttribute("id");
this.bEditMode = (this.getAttribute("data-edit-mode") === "edit");
this.SetupGrid();
this.BindEvents();
}
BindEvents() {
document.getElementById('ibo-dashboard-menu-edit-'+this.sId)?.addEventListener('click', (e) => {
e.preventDefault();
this.ToggleEditMode();
document.getElementById('ibo-dashboard-menu-edit-'+this.sId)?.classList.toggle('active', this.GetEditMode());
});
this.querySelector('[data-role="ibo-button"][name="save"]')?.addEventListener('click', (e) => {
e.preventDefault();
this.Save()
});
this.querySelector('[data-role="ibo-button"][name="cancel"]')?.addEventListener('click', (e) => {
e.preventDefault();
if (this.aLastSavedState) {
this.Load(this.aLastSavedState);
}
this.SetEditMode(false);
});
// TODO 3.3 Add event listener to dashboard toggler to get custom/default dashboard switching
// TODO 3.3 require load method that's not finished yet
// Bind IboDashboard object to these listener so we can access current instance
this._ListenToDashletFormSubmission = this._ListenToDashletFormSubmission.bind(this);
this._ListenToDashletFormCancellation = this._ListenToDashletFormCancellation.bind(this);
}
SetupGrid() {
if(this.oGrid !== null){
return;
}
this.oGrid = this.querySelector('ibo-dashboard-grid');
}
GetEditMode() {
return this.bEditMode;
}
ToggleEditMode(){
this.SetEditMode(!this.bEditMode);
}
SetEditMode(bEditMode) {
this.bEditMode = bEditMode;
this.oGrid.SetEditable(this.bEditMode);
if(this.bEditMode){
// TODO 3.3 If we are in default dashboard display, change to custom to allow editing
// TODO 3.3 Get the custom dashboard and load it, show a tooltip on the dashboard toggler to explain that we switched to custom mode
this.aLastSavedState = this.Serialize(true);
this.setAttribute("data-edit-mode", "edit");
}
else{
this.setAttribute("data-edit-mode", "view");
}
}
AddNewDashlet(sDashletClass, sDashletValues, aDashletOptions = {}) {
let sNewDashletUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet&dashlet_class='+encodeURIComponent(sDashletClass);
if(sDashletValues.length > 0) {
sNewDashletUrl += '&values=' + encodeURIComponent(sDashletValues);
}
fetch(sNewDashletUrl)
.then(async data => {
const sDashletId = this.oGrid.AddDashlet(await data.text(), aDashletOptions);
// TODO 3.3 Either open the dashlet form right away, or just enter edit mode
this.EditDashlet(sDashletId);
})
}
RefreshDashlet(oDashlet) {
let sGetDashletUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet&dashlet_class=' + encodeURIComponent(oDashlet.sType)
+'&dashlet_id=' + encodeURIComponent(oDashlet.sDashletId);
if(oDashlet.formData.length > 0) {
sGetDashletUrl += '&values=' + encodeURIComponent(oDashlet.formData);
}
return fetch(sGetDashletUrl)
.then(async data => {
this.oGrid.RefreshDashlet(await data.text());
});
}
HideDashletTogglers() {
const aTogglers = document.querySelector('.ibo-dashlet-panel--entries');
aTogglers.classList.add('ibo-is-hidden');
}
ShowDashletTogglers() {
const aTogglers = document.querySelector('.ibo-dashlet-panel--entries');
aTogglers.classList.remove('ibo-is-hidden');
}
SetDashletForm(sFormData) {
const oFormContainer = document.querySelector('.ibo-dashlet-panel--form-container');
oFormContainer.innerHTML = sFormData;
oFormContainer.classList.remove('ibo-is-hidden');
}
ClearDashletForm() {
const oFormContainer = document.querySelector('.ibo-dashlet-panel--form-container');
oFormContainer.innerHTML = '';
oFormContainer.classList.add('ibo-is-hidden');
}
DisableFormButtons() {
const aButtons = this.querySelectorAll('.ibo-dashboard--form--actions button');
aButtons.forEach( (oButton) => {
oButton.setAttribute('disabled', 'disabled');
});
}
EnableFormButtons() {
const aButtons = this.querySelectorAll('.ibo-dashboard--form--actions button');
aButtons.forEach( (oButton) => {
oButton.removeAttribute('disabled');
});
}
EditDashlet(sDashletId) {
const oDashlet = this.oGrid.GetDashletElement(sDashletId);
const me = this;
// Create backdrop to block interactions with other dashlets
if(this.oGrid.querySelector('.ibo-dashboard--grid--backdrop') === null) {
const oBackdrop = document.createElement("div");
oBackdrop.classList.add('ibo-dashboard--grid--backdrop');
this.oGrid.append(oBackdrop);
}
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'edit');
// Disable dashboard buttons so we need to finish this edition first
this.DisableFormButtons();
// Fetch dashlet form from server
let sGetashletFormUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet_form&dashlet_class='+encodeURIComponent(oDashlet.sType);
if(oDashlet.formData.length > 0) {
sGetashletFormUrl += '&values=' + encodeURIComponent(oDashlet.formData);
}
fetch(sGetashletFormUrl)
.then(async formData => {
const sFormData = await formData.text();
this.HideDashletTogglers();
this.SetDashletForm(sFormData);
// Listen to form submission event and cancellation
document.addEventListener('itop:TurboStreamEvent', me._ListenToDashletFormSubmission);
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').addEventListener('click', me._ListenToDashletFormCancellation);
});
}
_ListenToDashletFormSubmission(event) {
const oDashlet = this.querySelector('ibo-dashlet[data-edit-mode="edit"]');
const sDashletId = oDashlet.GetDashletId();
if(event.detail.id === oDashlet.sType + '-turbo-stream-event' && event.detail.valid === "1") {
// Remove events
document.addEventListener('itop:TurboStreamEvent', this._ListenToDashletFormSubmission);
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').removeEventListener('click', this._ListenToDashletFormCancellation);
// Notify it all went well
CombodoToast.OpenToast('Dashlet created/updated', 'success');
// Clean edit mode
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'view');
this.ShowDashletTogglers();
this.ClearDashletForm();
// Update local dashlet and refresh it
oDashlet.formData = event.detail.view_data;
this.RefreshDashlet(oDashlet);
// Re-enable dashboard buttons
this.EnableFormButtons();
}
}
_ListenToDashletFormCancellation(event) {
const oDashlet = this.querySelector('ibo-dashlet[data-edit-mode="edit"]');
const sDashletId = oDashlet.GetDashletId();
// Remove events
document.addEventListener('itop:TurboStreamEvent', this._ListenToDashletFormSubmission);
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').removeEventListener('click', this._ListenToDashletFormCancellation);
// Clean edit mode
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'view');
this.ShowDashletTogglers();
this.ClearDashletForm();
// Re-enable dashboard buttons
this.EnableFormButtons();
// TODO 3.3 If this is an addition, remove the previewed dashlet
// TODO 3.3 If this is an edition, revert the dashlet to its initial state
}
CloneDashlet(sDashletId) {
this.oGrid.CloneDashlet(sDashletId);
}
RemoveDashlet(sDashletId) {
this.oGrid.RemoveDashlet(sDashletId);
}
RefreshFromBackend(bCustomDashboard = false) {
const sLoadDashboardUrl = GetAbsoluteUrlAppRoot() + `/pages/UI.php?route=dashboard.load&id=${this.sId}&custom=${bCustomDashboard ? 'true' : 'false'}`;
fetch(sLoadDashboardUrl)
.then(async oResponse => {
const oDashletData = await oResponse.json();
this.Load(oDashletData);
}
)
}
Serialize(bIncludeHtml = false) {
const sDashboardTitle = this.querySelector('.ibo-dashboard--form--inputs input[name="dashboard_title"]').value;
const sDashboardRefreshRate = this.querySelector('.ibo-dashboard--form--inputs select[name="refresh_interval"]').value;
const aSerializedGrid = this.oGrid.Serialize(bIncludeHtml);
return {
schema_version: this.schemaVersion,
id: this.sId,
title: sDashboardTitle,
refresh: sDashboardRefreshRate,
pos_dashlets: aSerializedGrid,
_token: ":)"
};
}
Save() {
// This payload shape is expected by the server
const aPayload = this.Serialize();
let sSaveUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.save&values='+encodeURIComponent(JSON.stringify(aPayload));
fetch(sSaveUrl)
.then(async data => {
const res = await data.json();
if(res.status === 'ok') {
CombodoToast.OpenToast(res.message, 'success');
this.aLastSavedState = this.Serialize(true);
this.SetEditMode(false);
} else {
CombodoToast.OpenToast(res.message, 'error');
}
})
}
Load(aSaveState) {
try {
// Validate schema version
if (aSaveState.schema_version !== this.schemaVersion) {
CombodoToast.OpenToast('Somehow, we got an incompatible dashboard schema version.', 'error');
return false;
}
// Update dashboard data
this.sId = aSaveState.id;
this.sTitle = aSaveState.title || "";
this.iRefreshRate = parseInt(aSaveState.refresh, 10) || 0;
// Update form inputs if they exist
const oTitleInput = this.querySelector('.ibo-dashboard--form--inputs input[name="dashboard_title"]');
if (oTitleInput) {
oTitleInput.value = this.sTitle;
}
const oRefreshSelect = this.querySelector('.ibo-dashboard--form--inputs select[name="refresh_interval"]');
if (oRefreshSelect) {
oRefreshSelect.value = aSaveState.refresh;
}
// Clear existing grid
this.ClearGrid();
// Load dashlets
const aDashletSlots = aSaveState.pos_dashlets || {};
for (const [sDashletId, aDashletData] of Object.entries(aDashletSlots)) {
const iPosX = aDashletData.position_x;
const iPosY = aDashletData.position_y;
const iWidth = aDashletData.width;
const iHeight = aDashletData.height;
const aDashlet = aDashletData.dashlet;
// We store the dashlet component in the HTML, not only the rendered dashlet
const sDashetHtml = aDashlet.html;
// Add dashlet to grid with its position and size
this.oGrid.AddDashlet(sDashetHtml, {
x: iPosX,
y: iPosY,
w: iWidth,
h: iHeight,
autoPosition: false
});
}
// Update last saved state
this.aLastSavedState = aSaveState;
return true;
} catch (error) {
console.error('Error loading dashboard state:', error);
CombodoToast.OpenToast('Error loading dashboard state', 'error');
return false;
}
}
ClearGrid() {
this.oGrid.ClearGrid();
}
DisplayError(sMessage, sSeverity = 'error') {
// TODO 3.3: Make this real
this.setAttribute("data-edit-mode", "error");
}
}
customElements.define('ibo-dashboard', IboDashboard);

View File

@@ -1,68 +0,0 @@
class IboDashlet extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
/** @type {string} */
this.sDashletId = this.GetDashletId();
/** @type {string} */
this.sType = this.GetDashletType();
/** @type {Object} */
this.formData = this.GetFormData();
/** @type {Object} unused yet */
this.meta = {};
this.BindEvents();
}
BindEvents() {
// Bind any dashlet-specific events here
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-edit"]')?.addEventListener('click', (e) => {
this.closest('ibo-dashboard')?.EditDashlet(this.sDashletId);
});
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-clone"]')?.addEventListener('click', (e) => {
this.closest('ibo-dashboard')?.CloneDashlet(this.sDashletId);
});
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-remove"]')?.addEventListener('click', (e) => {
this.closest('ibo-dashboard')?.RemoveDashlet(this.sDashletId);
});
}
GetDashletId() {
return this.getAttribute('data-dashlet-id');
}
GetDashletType() {
return this.getAttribute("data-dashlet-type") || "";
}
GetFormData() {
return this.getAttribute("data-form-view-data") || "";
}
static MakeNew(sDashlet) {
const oDashlet = document.createElement('ibo-dashlet');
oDashlet.innerHTML = sDashlet;
return oDashlet;
}
Serialize(bIncludeHtml = false) {
// TODO 3.3 Should we use getters ?
let aDashletData = {
id: this.sDashletId,
type: this.sType,
properties: JSON.parse(this.formData),
};
if(bIncludeHtml) {
aDashletData.html = this.outerHTML;
}
return aDashletData;
}
}
customElements.define('ibo-dashlet', IboDashlet);

View File

@@ -130,27 +130,6 @@ return array(
'CheckableExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
'Collator' => $vendorDir . '/symfony/polyfill-intl-icu/Resources/stubs/Collator.php',
'Combodo\\iTop\\Application\\Branding' => $baseDir . '/sources/Application/Branding.php',
'Combodo\\iTop\\Application\\Dashboard\\Controller\\DashboardController' => $baseDir . '/sources/Application/Dashboard/Controller/DashboardController.php',
'Combodo\\iTop\\Application\\Dashboard\\DashboardException' => $baseDir . '/sources/Application/Dashboard/DashboardException.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashboardFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashboardFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashletFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletPropertiesFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashletPropertiesFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\Layout\\DashboardLayoutGrid' => $baseDir . '/sources/Application/Dashboard/Layout/DashboardLayoutGrid.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletBadge' => $baseDir . '/sources/Application/Dashlet/Core/DashletBadge.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupBy' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupBy.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByBars' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByBars.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByPie' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByPie.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByTable' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByTable.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderDynamic' => $baseDir . '/sources/Application/Dashlet/Core/DashletHeaderDynamic.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderStatic' => $baseDir . '/sources/Application/Dashlet/Core/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletObjectList' => $baseDir . '/sources/Application/Dashlet/Core/DashletObjectList.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletPlainText' => $baseDir . '/sources/Application/Dashlet/Core/DashletPlainText.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletProxy' => $baseDir . '/sources/Application/Dashlet/Core/DashletProxy.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletUnknown' => $baseDir . '/sources/Application/Dashlet/Core/DashletUnknown.php',
'Combodo\\iTop\\Application\\Dashlet\\Dashlet' => $baseDir . '/sources/Application/Dashlet/Dashlet.php',
'Combodo\\iTop\\Application\\Dashlet\\DashletException' => $baseDir . '/sources/Application/Dashlet/DashletException.php',
'Combodo\\iTop\\Application\\Dashlet\\DashletFactory' => $baseDir . '/sources/Application/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\Dashlet\\Service\\DashletService' => $baseDir . '/sources/Application/Dashlet/Service/DashletService.php',
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => $baseDir . '/sources/Application/EventRegister/ApplicationEvents.php',
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => $baseDir . '/sources/Application/Helper/CKEditorHelper.php',
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => $baseDir . '/sources/Application/Helper/ExportHelper.php',
@@ -191,7 +170,6 @@ return array(
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletFactory' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletHeaderStatic' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletPlainText' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletPlainText.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletWrapper' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletWrapper.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableConfig\\DataTableConfig' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTableConfig/DataTableConfig.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableSettings' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTableSettings.php',
@@ -292,13 +270,8 @@ return array(
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryFormFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardColumn' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardColumn.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGrid' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGrid.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGridSlot' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGridSlot.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardLayout' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardLayout.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardRow' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardRow.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletEntry' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletEntry.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanel' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanelFactory' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\Column' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/Column/Column.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\ColumnUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\MultiColumn' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/MultiColumn.php',
@@ -510,7 +483,6 @@ return array(
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => $baseDir . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceImageFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceImageFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => $baseDir . '/sources/Forms/Block/Base/CollectionBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
@@ -518,7 +490,6 @@ return array(
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => $baseDir . '/sources/Forms/Block/Base/HiddenFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => $baseDir . '/sources/Forms/Block/Base/IntegerFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => $baseDir . '/sources/Forms/Block/Base/NumberFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => $baseDir . '/sources/Forms/Block/Base/PolymorphicFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
@@ -586,19 +557,15 @@ return array(
'Combodo\\iTop\\PropertyType\\PropertyTypeFactory' => $baseDir . '/sources/PropertyType/PropertyTypeFactory.php',
'Combodo\\iTop\\PropertyType\\PropertyTypeService' => $baseDir . '/sources/PropertyType/PropertyTypeService.php',
'Combodo\\iTop\\PropertyType\\Serializer\\SerializerException' => $baseDir . '/sources/PropertyType/Serializer/SerializerException.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => $baseDir . '/sources/PropertyType/Serializer/XMLEncoder.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLNormalizer' => $baseDir . '/sources/PropertyType/Serializer/XMLNormalizer.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLSerializer' => $baseDir . '/sources/PropertyType/Serializer/XMLSerializer.php',
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => $baseDir . '/sources/PropertyType/ValueType/AbstractValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => $baseDir . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => $baseDir . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => $baseDir . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',
@@ -709,6 +676,19 @@ return array(
'DashboardLayoutThreeCols' => $baseDir . '/application/dashboardlayout.class.inc.php',
'DashboardLayoutTwoCols' => $baseDir . '/application/dashboardlayout.class.inc.php',
'DashboardMenuNode' => $baseDir . '/application/menunode.class.inc.php',
'Dashlet' => $baseDir . '/application/dashlet.class.inc.php',
'DashletBadge' => $baseDir . '/application/dashlet.class.inc.php',
'DashletEmptyCell' => $baseDir . '/application/dashlet.class.inc.php',
'DashletGroupBy' => $baseDir . '/application/dashlet.class.inc.php',
'DashletGroupByBars' => $baseDir . '/application/dashlet.class.inc.php',
'DashletGroupByPie' => $baseDir . '/application/dashlet.class.inc.php',
'DashletGroupByTable' => $baseDir . '/application/dashlet.class.inc.php',
'DashletHeaderDynamic' => $baseDir . '/application/dashlet.class.inc.php',
'DashletHeaderStatic' => $baseDir . '/application/dashlet.class.inc.php',
'DashletObjectList' => $baseDir . '/application/dashlet.class.inc.php',
'DashletPlainText' => $baseDir . '/application/dashlet.class.inc.php',
'DashletProxy' => $baseDir . '/application/dashlet.class.inc.php',
'DashletUnknown' => $baseDir . '/application/dashlet.class.inc.php',
'Datamatrix' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php',

View File

@@ -516,27 +516,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'CheckableExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
'Collator' => __DIR__ . '/..' . '/symfony/polyfill-intl-icu/Resources/stubs/Collator.php',
'Combodo\\iTop\\Application\\Branding' => __DIR__ . '/../..' . '/sources/Application/Branding.php',
'Combodo\\iTop\\Application\\Dashboard\\Controller\\DashboardController' => __DIR__ . '/../..' . '/sources/Application/Dashboard/Controller/DashboardController.php',
'Combodo\\iTop\\Application\\Dashboard\\DashboardException' => __DIR__ . '/../..' . '/sources/Application/Dashboard/DashboardException.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashboardFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashboardFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashletFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletPropertiesFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashletPropertiesFormBlock.php',
'Combodo\\iTop\\Application\\Dashboard\\Layout\\DashboardLayoutGrid' => __DIR__ . '/../..' . '/sources/Application/Dashboard/Layout/DashboardLayoutGrid.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletBadge' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletBadge.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupBy' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupBy.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByBars' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByBars.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByPie' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByPie.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByTable' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByTable.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderDynamic' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletHeaderDynamic.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderStatic' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletObjectList' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletObjectList.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletPlainText' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletPlainText.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletProxy' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletProxy.php',
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletUnknown' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletUnknown.php',
'Combodo\\iTop\\Application\\Dashlet\\Dashlet' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Dashlet.php',
'Combodo\\iTop\\Application\\Dashlet\\DashletException' => __DIR__ . '/../..' . '/sources/Application/Dashlet/DashletException.php',
'Combodo\\iTop\\Application\\Dashlet\\DashletFactory' => __DIR__ . '/../..' . '/sources/Application/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\Dashlet\\Service\\DashletService' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Service/DashletService.php',
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => __DIR__ . '/../..' . '/sources/Application/EventRegister/ApplicationEvents.php',
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/CKEditorHelper.php',
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/ExportHelper.php',
@@ -577,7 +556,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletHeaderStatic' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletHeaderStatic.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletPlainText' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletPlainText.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletWrapper' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletWrapper.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTable.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableConfig\\DataTableConfig' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTableConfig/DataTableConfig.php',
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableSettings' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTableSettings.php',
@@ -678,13 +656,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryFormFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardColumn' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardColumn.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGrid' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGrid.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGridSlot' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGridSlot.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardLayout' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardLayout.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardRow' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardRow.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletEntry' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletEntry.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanel.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanelFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanelFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\Column' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/Column/Column.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\ColumnUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php',
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\MultiColumn' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/MultiColumn.php',
@@ -896,7 +869,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceImageFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceImageFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CollectionBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
@@ -904,7 +876,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/HiddenFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/IntegerFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/NumberFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/PolymorphicFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
@@ -972,19 +943,15 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\PropertyType\\PropertyTypeFactory' => __DIR__ . '/../..' . '/sources/PropertyType/PropertyTypeFactory.php',
'Combodo\\iTop\\PropertyType\\PropertyTypeService' => __DIR__ . '/../..' . '/sources/PropertyType/PropertyTypeService.php',
'Combodo\\iTop\\PropertyType\\Serializer\\SerializerException' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/SerializerException.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLEncoder.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLNormalizer' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLNormalizer.php',
'Combodo\\iTop\\PropertyType\\Serializer\\XMLSerializer' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLSerializer.php',
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/AbstractValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',
@@ -1095,6 +1062,19 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'DashboardLayoutThreeCols' => __DIR__ . '/../..' . '/application/dashboardlayout.class.inc.php',
'DashboardLayoutTwoCols' => __DIR__ . '/../..' . '/application/dashboardlayout.class.inc.php',
'DashboardMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
'Dashlet' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletBadge' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletEmptyCell' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletGroupBy' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletGroupByBars' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletGroupByPie' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletGroupByTable' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletHeaderDynamic' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletHeaderStatic' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletObjectList' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletPlainText' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletProxy' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'DashletUnknown' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
'Datamatrix' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php',

16
node_modules/.package-lock.json generated vendored
View File

@@ -186,22 +186,6 @@
"delegate": "^3.1.2"
}
},
"node_modules/gridstack": {
"version": "12.4.2",
"resolved": "https://registry.npmjs.org/gridstack/-/gridstack-12.4.2.tgz",
"integrity": "sha512-aXbJrQpi3LwpYXYOr4UriPM5uc/dPcjK01SdOE5PDpx2vi8tnLhU7yBg/1i4T59UhNkG/RBfabdFUObuN+gMnw==",
"funding": [
{
"type": "paypal",
"url": "https://www.paypal.me/alaind831"
},
{
"type": "venmo",
"url": "https://www.venmo.com/adumesny"
}
],
"license": "MIT"
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",

21
node_modules/gridstack/LICENSE generated vendored
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019-2025 Alain Dumesny. v0.4.0 and older (c) 2014-2018 Pavel Reznikov, Dylan Weiss
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

565
node_modules/gridstack/README.md generated vendored
View File

@@ -1,565 +0,0 @@
# gridstack.js
[![NPM version](https://img.shields.io/npm/v/gridstack.svg)](https://www.npmjs.com/package/gridstack)
[![Coverage Status](https://coveralls.io/repos/github/gridstack/gridstack.js/badge.svg?branch=develop)](https://coveralls.io/github/gridstack/gridstack.js?branch=develop)
[![downloads](https://img.shields.io/npm/dm/gridstack.svg)](https://www.npmjs.com/package/gridstack)
Mobile-friendly modern Typescript library for dashboard layout and creation. Making a drag-and-drop, multi-column responsive dashboard has never been easier. Has multiple bindings and works great with [Angular](https://angular.io/) (included), [React](https://reactjs.org/), [Vue](https://vuejs.org/), [Knockout.js](http://knockoutjs.com), [Ember](https://www.emberjs.com/) and others (see [frameworks](#specific-frameworks) section).
Inspired by no-longer maintained gridster, built with love.
Check http://gridstackjs.com and [these demos](http://gridstackjs.com/demo/).
If you find this lib useful, please donate [PayPal](https://www.paypal.me/alaind831) (use **“send to a friend”** to avoid 3% fee) or [Venmo](https://www.venmo.com/adumesny) (adumesny) and help support it!
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/alaind831)
[![Donate](https://img.shields.io/badge/Donate-Venmo-g.svg)](https://www.venmo.com/adumesny)
Join us on Slack: [https://gridstackjs.slack.com](https://join.slack.com/t/gridstackjs/shared_invite/zt-3978nsff6-HDNE_N45DydP36NBSV9JFQ)
<!-- [![Slack Status](https://gridstackjs.com/badge.svg)](https://gridstackjs.slack.com) -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Demo and API Documentation](#demo-and-api-documentation)
- [Usage](#usage)
- [Install](#install)
- [Include](#include)
- [Basic usage](#basic-usage)
- [Requirements](#requirements)
- [Specific frameworks](#specific-frameworks)
- [Extend Library](#extend-library)
- [Extend Engine](#extend-engine)
- [Change grid columns](#change-grid-columns)
- [Custom columns CSS (OLD, not needed with v12+)](#custom-columns-css-old-not-needed-with-v12)
- [Override resizable/draggable options](#override-resizabledraggable-options)
- [Touch devices support](#touch-devices-support)
- [Migrating](#migrating)
- [Migrating to v0.6](#migrating-to-v06)
- [Migrating to v1](#migrating-to-v1)
- [Migrating to v2](#migrating-to-v2)
- [Migrating to v3](#migrating-to-v3)
- [Migrating to v4](#migrating-to-v4)
- [Migrating to v5](#migrating-to-v5)
- [Migrating to v6](#migrating-to-v6)
- [Migrating to v7](#migrating-to-v7)
- [Migrating to v8](#migrating-to-v8)
- [Migrating to v9](#migrating-to-v9)
- [Migrating to v10](#migrating-to-v10)
- [Migrating to v11](#migrating-to-v11)
- [Migrating to v12](#migrating-to-v12)
- [jQuery Application](#jquery-application)
- [Changes](#changes)
- [Usage Trend](#usage-trend)
- [The Team](#the-team)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# Demo and API Documentation
Please visit http://gridstackjs.com and [these demos](http://gridstackjs.com/demo/), and complete [API documentation](https://gridstack.github.io/gridstack.js/doc/html/) ([markdown](https://github.com/gridstack/gridstack.js/tree/master/doc/API.md))
# Usage
## Install
[![NPM version](https://img.shields.io/npm/v/gridstack.svg)](https://www.npmjs.com/package/gridstack)
```js
yarn add gridstack
// or
npm install --save gridstack
```
## Include
ES6 or Typescript
```js
import 'gridstack/dist/gridstack.min.css';
import { GridStack } from 'gridstack';
```
Alternatively (single combined file, notice the -all.js) in html
```html
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
<script src="node_modules/gridstack/dist/gridstack-all.js"></script>
```
**Note**: IE support was dropped in v2, but restored in v4.4 by an external contributor (I have no interest in testing+supporting obsolete browser so this likely will break again in the future) and DROPPED again in v12 (css variable needed).
You can use the es5 files and polyfill (larger) for older browser instead. For example:
```html
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
<script src="node_modules/gridstack/dist/es5/gridstack-poly.js"></script>
<script src="node_modules/gridstack/dist/es5/gridstack-all.js"></script>
```
## Basic usage
creating items dynamically...
```js
// ...in your HTML
<div class="grid-stack"></div>
// ...in your script
var grid = GridStack.init();
grid.addWidget({w: 2, content: 'item 1'});
```
... or creating from list
```js
// using serialize data instead of .addWidget()
const serializedData = [
{x: 0, y: 0, w: 2, h: 2},
{x: 2, y: 3, w: 3, content: 'item 2'},
{x: 1, y: 3}
];
grid.load(serializedData);
```
... or DOM created items
```js
// ...in your HTML
<div class="grid-stack">
<div class="grid-stack-item">
<div class="grid-stack-item-content">Item 1</div>
</div>
<div class="grid-stack-item" gs-w="2">
<div class="grid-stack-item-content">Item 2 wider</div>
</div>
</div>
// ...in your script
GridStack.init();
```
...or see list of all [API and options](https://github.com/gridstack/gridstack.js/tree/master/doc) available.
see [stackblitz sample](https://stackblitz.com/edit/gridstack-demo) as running example too.
## Requirements
GridStack no longer requires external dependencies as of v1 (lodash was removed in v0.5 and jquery API in v1). v3 is a complete HTML5 re-write removing need for jquery. v6 is native mouse and touch event for mobile support, and no longer have jquery-ui version. All you need to include now is `gridstack-all.js` and `gridstack.min.css` (layouts are done using CSS column based %).
## Specific frameworks
search for ['gridstack' under NPM](https://www.npmjs.com/search?q=gridstack&ranking=popularity) for latest, more to come...
- **Angular**: we ship out of the box an Angular wrapper - see <a href="https://github.com/gridstack/gridstack.js/tree/master/angular" target="_blank">Angular Component</a>.
- **Angular9**: [lb-gridstack](https://github.com/pfms84/lb-gridstack) Note: very old v0.3 gridstack instance so recommend for **concept ONLY if you wish to use directive instead**. Code has **not been vented** at as I use components.
- **AngularJS**: [gridstack-angular](https://github.com/kdietrich/gridstack-angular)
- **Ember**: [ember-gridstack](https://github.com/yahoo/ember-gridstack)
- **knockout**: see [demo](https://gridstackjs.com/demo/knockout.html) using component, but check [custom bindings ticket](https://github.com/gridstack/gridstack.js/issues/465) which is likely better approach.
- **Rails**: [gridstack-js-rails](https://github.com/randoum/gridstack-js-rails)
- **React**: work in progress to have wrapper code: see <a href="https://github.com/gridstack/gridstack.js/tree/master/react" target="_blank">React Component</a>. But also see [demo](https://gridstackjs.com/demo/react.html) with [src](https://github.com/gridstack/gridstack.js/tree/master/demo/react.html), or [react-gridstack-example](https://github.com/Inder2108/react-gridstack-example/tree/master/src/App.js), or read on what [hooks to use](https://github.com/gridstack/gridstack.js/issues/735#issuecomment-329888796)
- **Vue**: see [demo](https://gridstackjs.com/demo/vue3js.html) with [v3 src](https://github.com/gridstack/gridstack.js/tree/master/demo/vue3js.html) or [v2 src](https://github.com/gridstack/gridstack.js/tree/master/demo/vue2js.html)
- **Aurelia**: [aurelia-gridstack](https://github.com/aurelia-ui-toolkits/aurelia-gridstack), see [demo](https://aurelia-ui-toolkits.github.io/aurelia-gridstack/)
## Extend Library
You can easily extend or patch gridstack with code like this:
```js
// extend gridstack with our own custom method
GridStack.prototype.printCount = function() {
console.log('grid has ' + this.engine.nodes.length + ' items');
};
let grid = GridStack.init();
// you can now call
grid.printCount();
```
## Extend Engine
You can now (5.1+) easily create your own layout engine to further customize your usage. Here is a typescript example
```ts
import { GridStack, GridStackEngine, GridStackNode, GridStackMoveOpts } from 'gridstack';
class CustomEngine extends GridStackEngine {
/** refined this to move the node to the given new location */
public override moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {
// keep the same original X and Width and let base do it all...
o.x = node.x;
o.w = node.w;
return super.moveNode(node, o);
}
}
GridStack.registerEngine(CustomEngine); // globally set our custom class
```
## Change grid columns
GridStack makes it very easy if you need [1-12] columns out of the box (default is 12), but you always need **2 things** if you need to customize this:
1) Change the `column` grid option when creating a grid to your number N
```js
GridStack.init( {column: N} );
```
NOTE: step 2 is OLD and not needed with v12+ which uses CSS variables instead of classes
2) also include `gridstack-extra.css` if **N < 12** (else custom CSS - see next). Without these, things will not render/work correctly.
```html
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
<link href="node_modules/gridstack/dist/gridstack-extra.min.css" rel="stylesheet"/>
<div class="grid-stack">...</div>
```
Note: class `.grid-stack-N` will automatically be added and we include `gridstack-extra.min.css` which defines CSS for grids with custom [2-11] columns. Anything more and you'll need to generate the SASS/CSS yourself (see next).
See example: [2 grids demo](http://gridstack.github.io/gridstack.js/demo/two.html) with 6 columns
## Custom columns CSS (OLD, not needed with v12+)
NOTE: step is OLD and not needed with v12+ which uses CSS variables instead of classes
If you need > 12 columns or want to generate the CSS manually you will need to generate CSS rules for `.grid-stack-item[gs-w="X"]` and `.grid-stack-item[gs-x="X"]`.
For instance for 4-column grid you need CSS to be:
```css
.gs-4 > .grid-stack-item[gs-x="1"] { left: 25% }
.gs-4 > .grid-stack-item[gs-x="2"] { left: 50% }
.gs-4 > .grid-stack-item[gs-x="3"] { left: 75% }
.gs-4 > .grid-stack-item { width: 25% }
.gs-4 > .grid-stack-item[gs-w="2"] { width: 50% }
.gs-4 > .grid-stack-item[gs-w="3"] { width: 75% }
.gs-4 > .grid-stack-item[gs-w="4"] { width: 100% }
```
Better yet, here is a SCSS code snippet, you can use sites like [sassmeister.com](https://www.sassmeister.com/) to generate the CSS for you instead:
```scss
$columns: 20;
@function fixed($float) {
@return round($float * 1000) / 1000; // total 2+3 digits being %
}
.gs-#{$columns} > .grid-stack-item {
width: fixed(100% / $columns);
@for $i from 1 through $columns - 1 {
&[gs-x='#{$i}'] { left: fixed((100% / $columns) * $i); }
&[gs-w='#{$i+1}'] { width: fixed((100% / $columns) * ($i+1)); }
}
}
```
you can also use the SCSS [src/gridstack-extra.scss](https://github.com/gridstack/gridstack.js/tree/master/src/gridstack-extra.scss) included in NPM package and modify to add more columns.
Sample gulp command for 30 columns:
```js
gulp.src('node_modules/gridstack/dist/src/gridstack-extra.scss')
.pipe(replace('$start: 2 !default;','$start: 30;'))
.pipe(replace('$end: 11 !default;','$end: 30;'))
.pipe(sass({outputStyle: 'compressed'}))
.pipe(rename({extname: '.min.css'}))
.pipe(gulp.dest('dist/css'))
```
## Override resizable/draggable options
You can override default `resizable`/`draggable` options. For instance to enable other then bottom right resizing handle
you can init gridstack like:
```js
GridStack.init({
resizable: {
handles: 'e,se,s,sw,w'
}
});
```
## Touch devices support
gridstack v6+ now support mobile out of the box, with the addition of native touch event (along with mouse event) for drag&drop and resize.
Older versions (3.2+) required the jq version with added touch punch, but doesn't work well with nested grids.
This option is now the default:
```js
let options = {
alwaysShowResizeHandle: 'mobile' // true if we're on mobile devices
};
GridStack.init(options);
```
See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html).
# Migrating
## Migrating to v0.6
starting in 0.6.x `change` event are no longer sent (for pretty much most nodes!) when an item is just added/deleted unless it also changes other nodes (was incorrect and causing inefficiencies). You may need to track `added|removed` [events](https://github.com/gridstack/gridstack.js/tree/master/doc#events) if you didn't and relied on the old broken behavior.
## Migrating to v1
v1.0.0 removed Jquery from the API and external dependencies, which will require some code changes. Here is a list of the changes:
0. see previous step if not on v0.6 already
1. your code only needs to `import GridStack from 'gridstack'` or include `gridstack.all.js` and `gristack.css` (don't include other JS) and is recommended you do that as internal dependencies will change over time. If you are jquery based, see [jquery app](#jquery-application) section.
2. code change:
**OLD** initializing code + adding a widget + adding an event:
```js
// initialization returned Jquery element, requiring second call to get GridStack var
var grid = $('.grid-stack').gridstack(opts?).data('gridstack');
// returned Jquery element
grid.addWidget($('<div><div class="grid-stack-item-content"> test </div></div>'), undefined, undefined, 2, undefined, true);
// jquery event handler
$('.grid-stack').on('added', function(e, items) {/* items contains info */});
// grid access after init
var grid = $('.grid-stack').data('gridstack');
```
**NEW**
```js
// element identifier defaults to '.grid-stack', returns the grid
// Note: for Typescript use window.GridStack.init() until next native 2.x TS version
var grid = GridStack.init(opts?, element?);
// returns DOM element
grid.addWidget('<div><div class="grid-stack-item-content"> test </div></div>', {width: 2});
// Note: in 3.x it's ever simpler
// grid.addWidget({w:2, content: 'test'})
// event handler
grid.on('added', function(e, items) {/* items contains info */});
// grid access after init
var grid = el.gridstack; // where el = document.querySelector('.grid-stack') or other ways...
```
Other rename changes
```js
`GridStackUI` --> `GridStack`
`GridStackUI.GridStackEngine` --> `GridStack.Engine`
`grid.container` (jquery grid wrapper) --> `grid.el` // (grid DOM element)
`grid.grid` (GridStackEngine) --> `grid.engine`
`grid.setColumn(N)` --> `grid.column(N)` and `grid.column()` // to get value, old API still supported though
```
Recommend looking at the [many samples](./demo) for more code examples.
## Migrating to v2
make sure to read v1 migration first!
v2 is a Typescript rewrite of 1.x, removing all jquery events, using classes and overall code cleanup to support ES6 modules. Your code might need to change from 1.x
1. In general methods that used no args (getter) vs setter can't be used in TS when the arguments differ (set/get are also not function calls so API would have changed). Instead we decided to have <b>all set methods return</b> `GridStack` to they can be chain-able (ex: `grid.float(true).cellHeight(10).column(6)`). Also legacy methods that used to take many parameters will now take a single object (typically `GridStackOptions` or `GridStackWidget`).
```js
`addWidget(el, x, y, width, height)` --> `addWidget(el, {with: 2})`
// Note: in 2.1.x you can now just do addWidget({with: 2, content: "text"})
`float()` --> `getFloat()` // to get value
`cellHeight()` --> `getCellHeight()` // to get value
`verticalMargin` --> `margin` // grid options and API that applies to all 4 sides.
`verticalMargin()` --> `getMargin()` // to get value
```
2. event signatures are generic and not jquery-ui dependent anymore. `gsresizestop` has been removed as `resizestop|dragstop` are now called **after** the DOM attributes have been updated.
3. `oneColumnMode` would trigger when `window.width` < 768px by default. We now check for grid width instead (more correct and supports nesting). You might need to adjust grid `oneColumnSize` or `disableOneColumnMode`.
**Note:** 2.x no longer support legacy IE11 and older due to using more compact ES6 output and typecsript native code. You will need to stay at 1.x
## Migrating to v3
make sure to read v2 migration first!
v3 has a new HTML5 drag&drop plugging (63k total, all native code), while still allowing you to use the legacy jquery-ui version instead (188k), or a new static grid version (34k, no user drag&drop but full API support). You will need to decide which version to use as `gridstack.all.js` no longer exist (same is now `gridstack-jq.js`) - see [include info](#include).
**NOTE**: HTML5 version is almost on parity with the old jquery-ui based drag&drop. the `containment` (prevent a child from being dragged outside it's parent) and `revert` (not clear what it is for yet) are not yet implemented in initial release of v3.0.0.<br>
Also mobile devices don't support h5 `drag` events (will need to handle `touch`) whereas v3.2 jq version now now supports out of the box (see [v3.2 release](https://github.com/gridstack/gridstack.js/releases/tag/v3.2.0))
Breaking changes:
1. include (as mentioned) need to change
2. `GridStack.update(el, opt)` now takes single `GridStackWidget` options instead of only supporting (x,y,w,h) BUT legacy call in JS will continue working the same for now. That method is a complete re-write and does the right constrain and updates now for all the available params.
3. `locked()`, `move()`, `resize()`, `minWidth()`, `minHeight()`, `maxWidth()`, `maxHeight()` methods are hidden from Typescript (JS can still call for now) as they are just 1 liner wrapper around `update(el, opt)` anyway and will go away soon. (ex: `move(el, x, y)` => `update(el, {x, y})`)
4. item attribute like `data-gs-min-width` is now `gs-min-w`. We removed 'data-' from all attributes, and shorten 'width|height' to just 'w|h' to require less typing and more efficient (2k saved in .js alone!).
5. `GridStackWidget` used in most API `width|height|minWidth|minHeight|maxWidth|maxHeight` are now shorter `w|h|minW|minH|maxW|maxH` as well
## Migrating to v4
make sure to read v3 migration first!
v4 is a complete re-write of the collision and drag in/out heuristics to fix some very long standing request & bugs. It also greatly improved usability. Read the release notes for more detail.
**Unlikely** Breaking Changes (internal usage):
1. `removeTimeout` was removed (feedback over trash will be immediate - actual removal still on mouse up)
2. the following `GridStackEngine` methods changed (used internally, doesn't affect `GridStack` public API)
```js
// moved to 3 methods with new option params to support new code and pixel coverage check
`collision()` -> `collide(), collideAll(), collideCoverage()`
`moveNodeCheck(node, x, y, w, h)` -> `moveNodeCheck(node, opt: GridStackMoveOpts)`
`isNodeChangedPosition(node, x, y, w, h)` -> `changedPosConstrain(node, opt: GridStackMoveOpts)`
`moveNode(node, x, y, w, h, noPack)` -> `moveNode(node, opt: GridStackMoveOpts)`
```
3. removed old obsolete (v0.6-v1 methods/attrs) `getGridHeight()`, `verticalMargin`, `data-gs-current-height`,
`locked()`, `maxWidth()`, `minWidth()`, `maxHeight()`, `minHeight()`, `move()`, `resize()`
## Migrating to v5
make sure to read v4 migration first!
v5 does not have any breaking changes from v4, but a focus on nested grids in h5 mode:
You can now drag in/out of parent into nested child, with new API parameters values. See the release notes.
## Migrating to v6
the API did not really change from v5, but a complete re-write of Drag&Drop to use native `mouseevent` (instead of HTML draggable=true which is buggy on Mac Safari, and doesn't work on mobile devices) and `touchevent` (mobile), and we no longer have jquery ui option (wasn't working well for nested grids, didn't want to maintain legacy lib).
The main difference is you only need to include gridstack.js and get D&D (desktop and mobile) out of the box for the same size as h5 version.
## Migrating to v7
New addition, no API breakage per say. See release notes about creating sub-grids on the fly.
## Migrating to v8
Possible breaking change if you use nested grid JSON format, or original Angular wrapper, or relied on specific CSS paths. Also target is now ES2020 (see release notes).
* `GridStackOptions.subGrid` -> `GridStackOptions.subGridOpts` rename. We now have `GridStackWidget.subGridOpts` vs `GridStackNode.subGrid` (was both types which is error prone)
* `GridStackOptions.addRemoveCB` -> `GridStack.addRemoveCB` is now global instead of grid option
* removed `GridStackOptions.dragInOptions` since `GridStack.setupDragIn()` has it replaced since 4.0
* remove `GridStackOptions.minWidth` obsolete since 5.1, use `oneColumnSize` instead
* CSS rules removed `.grid-stack` prefix for anything already gs based, 12 column (default) now uses `.gs-12`, extra.css is less than 1/4th it original size!, `gs-min|max_w|h` attribute no longer written (but read)
## Migrating to v9
New addition - see release notes about `sizeToContent` feature.
Possible break:
* `GridStack.onParentResize()` is now called `onResize()` as grid now directly track size change, no longer involving parent per say to tell us anything. Note sure why it was public.
## Migrating to v10
we now support much richer responsive behavior with `GridStackOptions.columnOpts` including any breakpoint width:column pairs, or automatic column sizing.
breaking change:
* `disableOneColumnMode`, `oneColumnSize` have been removed (thought we temporary convert if you have them). use `columnOpts: { breakpoints: [{w:768, c:1}] }` for the same behavior.
* 1 column mode switch is no longer by default (`columnOpts` is not defined) as too many new users had issues. Instead set it explicitly (see above).
* `oneColumnModeDomSort` has been removed. Planning to support per column layouts at some future times. TBD
## Migrating to v11
* All instances of `el.innerHTML = 'some content'` have been removed for security reason as it opens up some potential for accidental XSS.
* Side panel drag&drop complete rewrite.
* new lazy loading option
**Breaking change:**
* V11 add new `GridStack.renderCB` that is called for you to create the widget content (entire GridStackWidget is passed so you can use id or some other field as logic) while GS creates the 2 needed parent divs + classes, unlike `GridStack.addRemoveCB` which doesn't create anything for you. Both can be handy for Angular/React/Vue frameworks.
* `addWidget(w: GridStackWidget)` is now the only supported format, no more string content passing. You will need to create content yourself as shown below, OR use `GridStack.createWidgetDivs()` to create parent divs, do the innerHtml, then call `makeWidget(el)` instead.
* if your code relies on `GridStackWidget.content` with real HTML (like a few demos) it is up to you to do this:
```ts
// NOTE: REAL apps would sanitize-html or DOMPurify before blinding setting innerHTML. see #2736
GridStack.renderCB = function(el: HTMLElement, w: GridStackNode) {
el.innerHTML = w.content;
};
// now you can create widgets like this again
let gridWidget = grid.addWidget({x, y, w, h, content: '<div>My html content</div>'});
```
**Potential breaking change:**
* BIG overall to how sidepanel helper drag&drop is done:
1. `clone()` helper is now passed full HTML element dragged, not an event on `grid-stack-item-content` so you can clone or set attr at the top.
2. use any class/structure you want for side panel items (see two.html)
3. `GridStack.setupDragIn()` now support associating a `GridStackWidget` for each sidepanel that will be used to define what to create on drop!
4. if no `GridStackWidget` is defined, the helper will now be inserted as is, and NOT original sidepanel item.
5. support DOM gs- attr as well as gridstacknode JSON (see two.html) alternatives.
## Migrating to v12
* column and cell height code has been re-writen to use browser CSS variables, and we no longer need a tons of custom CSS classes!
this fixes a long standing issue where people forget to include the right CSS for non 12 columns layouts, and a big speedup in many cases (many columns, or small cellHeight values).
**Potential breaking change:**
* `gridstack-extra.min.css` no longer exist, nor is custom column CSS classes needed. API/options hasn't changed.
* (v12.1) `ES5` folder content has been removed - was for IE support, which has been dropped.
* (v12.1) nested grid events are now sent to the main grid. You might have to adjust your workaround of this missing feature. nested.html demo has been adjusted.
# jQuery Application
This is **old and no longer apply to v6+**. You'll need to use v5.1.1 and before
```js
import 'gridstack/dist/gridstack.min.css';
import { GridStack } from 'gridstack';
import 'gridstack/dist/jq/gridstack-dd-jqueryui';
```
**Note**: `jquery` & `jquery-ui` are imported by name, so you will have to specify their location in your webpack (or equivalent) config file,
which means you can possibly bring your own version
```js
alias: {
'jquery': 'gridstack/dist/jq/jquery.js',
'jquery-ui': 'gridstack/dist/jq/jquery-ui.js',
'jquery.ui': 'gridstack/dist/jq/jquery-ui.js',
'jquery.ui.touch-punch': 'gridstack/dist/jq/jquery.ui.touch-punch.js',
},
```
Alternatively (single combined file) in html
```html
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
<!-- HTML5 drag&drop (70k) -->
<script src="node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- OR jquery-ui drag&drop (195k) -->
<script src="node_modules/gridstack/dist/gridstack-jq.js"></script>
<!-- OR static grid (40k) -->
<script src="node_modules/gridstack/dist/gridstack-static.js"></script>
```
We have a native HTML5 drag'n'drop through the plugin system (default), but the jquery-ui version can be used instead. It will bundle `jquery` (3.5.1) + `jquery-ui` (1.13.1 minimal drag|drop|resize) + `jquery-ui-touch-punch` (1.0.8 for mobile support) in `gridstack-jq.js`.
**NOTE: in v4, v3**: we ES6 module import jquery & jquery-ui by name, so you need to specify location of those .js files, which means you might be able to bring your own version as well. See the include instructions.
**NOTE: in v1.x** IFF you want to use gridstack-jq instead and your app needs to bring your own JQ version, you should **instead** include `gridstack-poly.min.js` (optional IE support) + `gridstack.min.js` + `gridstack.jQueryUI.min.js` after you import your JQ libs. But note that there are issue with jQuery and ES6 import (see [1306](https://github.com/gridstack/gridstack.js/issues/1306)).
As for events, you can still use `$(".grid-stack").on(...)` for the version that uses jquery-ui for things we don't support.
# Changes
View our change log [here](https://github.com/gridstack/gridstack.js/tree/master/doc/CHANGES.md).
# Usage Trend
[Usage Trend of gridstack](https://npm-compare.com/gridstack#timeRange=THREE_YEARS)
<a href="https://npm-compare.com/gridstack#timeRange=THREE_YEARS" target="_blank">
<img src="https://npm-compare.com/img/npm-trend/THREE_YEARS/gridstack.png" width="70%" alt="NPM Usage Trend of gridstack" />
</a>
# The Team
gridstack.js is currently maintained by [Alain Dumesny](https://github.com/adumesny), before that [Dylan Weiss](https://github.com/radiolips), originally created by [Pavel Reznikov](https://github.com/troolee). We appreciate [all contributors](https://github.com/gridstack/gridstack.js/graphs/contributors) for help.

View File

@@ -1,69 +0,0 @@
/**
* dd-base-impl.ts 12.4.2
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
*/
/**
* Type for event callback functions used in drag & drop operations.
* Can return boolean to indicate if the event should continue propagation.
*/
export type EventCallback = (event: Event) => boolean | void;
/**
* Abstract base class for all drag & drop implementations.
* Provides common functionality for event handling, enable/disable state,
* and lifecycle management used by draggable, droppable, and resizable implementations.
*/
export declare abstract class DDBaseImplement {
/**
* Returns the current disabled state.
* Note: Use enable()/disable() methods to change state as other operations need to happen.
*/
get disabled(): boolean;
/**
* Register an event callback for the specified event.
*
* @param event - Event name to listen for
* @param callback - Function to call when event occurs
*/
on(event: string, callback: EventCallback): void;
/**
* Unregister an event callback for the specified event.
*
* @param event - Event name to stop listening for
*/
off(event: string): void;
/**
* Enable this drag & drop implementation.
* Subclasses should override to perform additional setup.
*/
enable(): void;
/**
* Disable this drag & drop implementation.
* Subclasses should override to perform additional cleanup.
*/
disable(): void;
/**
* Destroy this drag & drop implementation and clean up resources.
* Removes all event handlers and clears internal state.
*/
destroy(): void;
/**
* Trigger a registered event callback if one exists and the implementation is enabled.
*
* @param eventName - Name of the event to trigger
* @param event - DOM event object to pass to the callback
* @returns Result from the callback function, if any
*/
triggerEvent(eventName: string, event: Event): boolean | void;
}
/**
* Interface for HTML elements extended with drag & drop options.
* Used to associate DD configuration with DOM elements.
*/
export interface HTMLElementExtendOpt<T> {
/** The HTML element being extended */
el: HTMLElement;
/** The drag & drop options/configuration */
option: T;
/** Method to update the options and return the DD implementation */
updateOption(T: any): DDBaseImplement;
}

Some files were not shown because too many files have changed in this diff Show More