410 lines
25 KiB
SQL
410 lines
25 KiB
SQL
create or replace package UDO_PKG_EQUIPDS as
|
||
|
||
/* Список выборок данных */
|
||
procedure LIST
|
||
(
|
||
COUT out clob -- Сериализованная таблица данных
|
||
);
|
||
|
||
/* Клиентское добавление "Выборки данных оборудования" */
|
||
procedure INS
|
||
(
|
||
SCODE in varchar2, -- Мнемокод
|
||
SNAME in varchar2, -- Наименование
|
||
NRN out number -- Регистрационный номер
|
||
);
|
||
|
||
/* Клиентское удаление "Выборки данных оборудования" */
|
||
procedure DEL
|
||
(
|
||
NRN in number -- Регистрационный номер
|
||
);
|
||
|
||
/* Список классов оборудования выборки данных */
|
||
procedure CM_LIST
|
||
(
|
||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
);
|
||
|
||
/* Клиентское добавление "Выборки данных оборудования (классы оборудования)" */
|
||
procedure CM_INS
|
||
(
|
||
NPRN in number, -- Родитель
|
||
SEQOBJKIND in varchar2, -- Класс оборудования
|
||
SUSERPROCS_DATA in varchar2, -- Процедура формирования
|
||
SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных
|
||
SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных
|
||
SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе
|
||
SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе
|
||
SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой
|
||
SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой
|
||
NRN out number -- Регистрационный номер
|
||
);
|
||
|
||
/* Клиентское удаление "Выборки данных оборудования (классы оборудования)" */
|
||
procedure CM_DEL
|
||
(
|
||
NRN in number -- Регистрационный номер
|
||
);
|
||
|
||
/* Список файлов данных класса оборудования */
|
||
procedure CMFL_LIST
|
||
(
|
||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
);
|
||
|
||
/* Список моделей класса оборудования */
|
||
procedure CMML_LIST
|
||
(
|
||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
);
|
||
|
||
/* Код доступного действия с моделью по единице оборудования */
|
||
function CMML_ACT_BY_EQCONFIG
|
||
(
|
||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||
) return number; -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
|
||
|
||
/* Список моделей по единице оборудования */
|
||
function CMML_LIST_BY_EQCONFIG
|
||
(
|
||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||
) return varchar2; -- Список моделей с системным разделителем по умолчанию
|
||
|
||
end UDO_PKG_EQUIPDS;
|
||
/
|
||
create or replace package body UDO_PKG_EQUIPDS as
|
||
|
||
/*
|
||
TODO: owner="root" created="06.08.2024"
|
||
text="Проверка прав доступа на работу с ""Выборками данных"""
|
||
*/
|
||
|
||
/* Список выборок данных */
|
||
procedure LIST
|
||
(
|
||
COUT out clob -- Сериализованная таблица данных
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
|
||
NCUR integer; -- Курсор документа для результата
|
||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||
XDS PKG_XMAKE.TNODE; -- Элемент для выборки данных
|
||
begin
|
||
/* Открываем документ */
|
||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||
/* Обходим выборки данных */
|
||
for C in (select T.RN NRN,
|
||
T.NAME SNAME
|
||
from UDO_T_EQUIPDS T
|
||
where T.COMPANY = NCOMPANY
|
||
order by T.NAME)
|
||
loop
|
||
XDS := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XDS,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'XDS',
|
||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'NRN',
|
||
SVALUE => C.NRN),
|
||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SNAME',
|
||
SVALUE => C.SNAME))));
|
||
end loop;
|
||
/* Формируем XML-представление ответа */
|
||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XDS);
|
||
/* Конвертируем в CLOB */
|
||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||
ITYPE => PKG_XMAKE.CONTENT_,
|
||
RNODE => XDOC,
|
||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||
/* Закрываем документ */
|
||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||
end LIST;
|
||
|
||
/* Клиентское добавление "Выборки данных оборудования" */
|
||
procedure INS
|
||
(
|
||
SCODE in varchar2, -- Мнемокод
|
||
SNAME in varchar2, -- Наименование
|
||
NRN out number -- Регистрационный номер
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация
|
||
begin
|
||
/* Добавляем запись */
|
||
UDO_PKG_EQUIPDS_BASE.INS(NCOMPANY => NCOMPANY, SCODE => SCODE, SNAME => SNAME, NRN => NRN);
|
||
end INS;
|
||
|
||
/* Клиентское удаление "Выборки данных оборудования" */
|
||
procedure DEL
|
||
(
|
||
NRN in number -- Регистрационный номер
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация
|
||
begin
|
||
/* Добавляем запись */
|
||
UDO_PKG_EQUIPDS_BASE.DEL(NRN => NRN, NCOMPANY => NCOMPANY);
|
||
end DEL;
|
||
|
||
/* Список классов оборудования выборки данных */
|
||
procedure CM_LIST
|
||
(
|
||
NEQUIPDS in number, -- Рег. номер выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
)
|
||
is
|
||
NCUR integer; -- Курсор документа для результата
|
||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||
XDSCM PKG_XMAKE.TNODE; -- Элемент для выборки данных
|
||
begin
|
||
/* Открываем документ */
|
||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||
/* Обходим классы оборудования заданной выборки данных */
|
||
for C in (select T.RN NRN,
|
||
OK.CODE SCODE,
|
||
OK.NAME SNAME
|
||
from UDO_T_EQUIPDSCM T,
|
||
EQOBJKIND OK
|
||
where T.PRN = NEQUIPDS
|
||
and T.EQOBJKIND = OK.RN
|
||
order by OK.CODE)
|
||
loop
|
||
XDSCM := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XDSCM,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'XDSCM',
|
||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'NRN',
|
||
SVALUE => C.NRN),
|
||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SCODE',
|
||
SVALUE => C.SCODE),
|
||
RATTRIBUTE02 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SNAME',
|
||
SVALUE => C.SNAME))));
|
||
end loop;
|
||
/* Формируем XML-представление ответа */
|
||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XDSCM);
|
||
/* Конвертируем в CLOB */
|
||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||
ITYPE => PKG_XMAKE.CONTENT_,
|
||
RNODE => XDOC,
|
||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||
/* Закрываем документ */
|
||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||
end CM_LIST;
|
||
|
||
/* Клиентское добавление "Выборки данных оборудования (классы оборудования)" */
|
||
procedure CM_INS
|
||
(
|
||
NPRN in number, -- Родитель
|
||
SEQOBJKIND in varchar2, -- Класс оборудования
|
||
SUSERPROCS_DATA in varchar2, -- Процедура формирования
|
||
SEXSSERVICE_UPLOAD in varchar2, -- Сервис обмена для выгрузки данных
|
||
SEXSSERVICEFN_UPLOAD in varchar2, -- Функция обмена для выгрузки данных
|
||
SEXSSERVICE_SEND_MD in varchar2, -- Сервис обмена для передачи внешней системе
|
||
SEXSSERVICEFN_SEND_MD in varchar2, -- Функция обмена для передачи внешней системе
|
||
SEXSSERVICE_SEND_RQ in varchar2, -- Сервис обмена для обработки внешней системой
|
||
SEXSSERVICEFN_SEND_RQ in varchar2, -- Функция обмена для обработки внешней системой
|
||
NRN out number -- Регистрационный номер
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация
|
||
NEQOBJKIND PKG_STD.TREF; -- Рег. номер класса оборудования
|
||
NUSERPROCS_DATA PKG_STD.TREF; -- Рег. номер процедуры формирования
|
||
NEXSSERVICEFN_UPLOAD PKG_STD.TREF; -- Рег. номер функции обмена для выгрузки данных
|
||
NEXSSERVICEFN_SEND_MD PKG_STD.TREF; -- Рег. номер Функции обмена для передачи внешней системе
|
||
NEXSSERVICEFN_SEND_RQ PKG_STD.TREF; -- Рег. номер функции обмена для обработки внешней системой
|
||
begin
|
||
/* Разыменуем ссылки */
|
||
UDO_PKG_EQUIPDS_BASE.CM_JOINS(NCOMPANY => NCOMPANY,
|
||
SEQOBJKIND => SEQOBJKIND,
|
||
SUSERPROCS_DATA => SUSERPROCS_DATA,
|
||
SEXSSERVICE_UPLOAD => SEXSSERVICE_UPLOAD,
|
||
SEXSSERVICEFN_UPLOAD => SEXSSERVICEFN_UPLOAD,
|
||
SEXSSERVICE_SEND_MD => SEXSSERVICE_SEND_MD,
|
||
SEXSSERVICEFN_SEND_MD => SEXSSERVICEFN_SEND_MD,
|
||
SEXSSERVICE_SEND_RQ => SEXSSERVICE_SEND_RQ,
|
||
SEXSSERVICEFN_SEND_RQ => SEXSSERVICEFN_SEND_RQ,
|
||
NEQOBJKIND => NEQOBJKIND,
|
||
NUSERPROCS_DATA => NUSERPROCS_DATA,
|
||
NEXSSERVICEFN_UPLOAD => NEXSSERVICEFN_UPLOAD,
|
||
NEXSSERVICEFN_SEND_MD => NEXSSERVICEFN_SEND_MD,
|
||
NEXSSERVICEFN_SEND_RQ => NEXSSERVICEFN_SEND_RQ);
|
||
/* Добавляем запись */
|
||
UDO_PKG_EQUIPDS_BASE.CM_INS(NPRN => NPRN,
|
||
NEQOBJKIND => NEQOBJKIND,
|
||
NUSERPROCS_DATA => NUSERPROCS_DATA,
|
||
NEXSSERVICEFN_UPLOAD => NEXSSERVICEFN_UPLOAD,
|
||
NEXSSERVICEFN_SEND_MD => NEXSSERVICEFN_SEND_MD,
|
||
NEXSSERVICEFN_SEND_RQ => NEXSSERVICEFN_SEND_RQ,
|
||
NRN => NRN);
|
||
end CM_INS;
|
||
|
||
/* Клиентское удаление "Выборки данных оборудования (классы оборудования)" */
|
||
procedure CM_DEL
|
||
(
|
||
NRN in number -- Регистрационный номер
|
||
)
|
||
is
|
||
begin
|
||
/* Добавляем запись */
|
||
UDO_PKG_EQUIPDS_BASE.CM_DEL(NRN => NRN);
|
||
end CM_DEL;
|
||
|
||
/* Список файлов данных класса оборудования */
|
||
procedure CMFL_LIST
|
||
(
|
||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
)
|
||
is
|
||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||
begin
|
||
/* Инициализируем таблицу данных */
|
||
RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE();
|
||
/* Добавляем в таблицу описание колонок */
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NRN',
|
||
SCAPTION => 'Рег. номер',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||
BVISIBLE => false);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SFILE_NAME',
|
||
SCAPTION => 'Имя',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SDESCR',
|
||
SCAPTION => 'Описание',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NSTATUS',
|
||
SCAPTION => 'Состояние',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SERR',
|
||
SCAPTION => 'Сообщение об ошибке',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BVISIBLE => false);
|
||
/* Обходим данные */
|
||
for C in (select T.RN NRN,
|
||
T.FILE_NAME SFILE_NAME,
|
||
T.DESCR SDESCR,
|
||
T.STATUS NSTATUS,
|
||
T.ERR SERR
|
||
from UDO_T_EQUIPDSCMFL T
|
||
where T.PRN = NEQUIPDSCM
|
||
order by T.RN)
|
||
loop
|
||
/* Добавляем колонки с данными */
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SFILE_NAME', SVALUE => C.SFILE_NAME);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SDESCR', SVALUE => C.SDESCR);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSTATUS', NVALUE => C.NSTATUS);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SERR', SVALUE => C.SERR);
|
||
/* Добавляем строку в таблицу */
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||
end loop;
|
||
/* Сериализуем описание */
|
||
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
||
end CMFL_LIST;
|
||
|
||
/* Список моделей класса оборудования */
|
||
procedure CMML_LIST
|
||
(
|
||
NEQUIPDSCM in number, -- Рег. номер класса оборудования выборки данных
|
||
COUT out clob -- Сериализованная таблица данных
|
||
)
|
||
is
|
||
RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы
|
||
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
|
||
begin
|
||
/* Инициализируем таблицу данных */
|
||
RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE();
|
||
/* Добавляем в таблицу описание колонок */
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NRN',
|
||
SCAPTION => 'Рег. номер',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||
BVISIBLE => false);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'STASK',
|
||
SCAPTION => 'Задача',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NPRECISION_P',
|
||
SCAPTION => 'Точность (план)',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NPRECISION_F',
|
||
SCAPTION => 'Точность (факт)',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NSTATUS',
|
||
SCAPTION => 'Состояние',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SERR',
|
||
SCAPTION => 'Сообщение об ошибке',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BVISIBLE => false);
|
||
/* Обходим данные */
|
||
for C in (select T.RN NRN,
|
||
T.TASK STASK,
|
||
T.PRECISION_P NPRECISION_P,
|
||
T.PRECISION_F NPRECISION_F,
|
||
T.STATUS NSTATUS,
|
||
T.ERR SERR
|
||
from UDO_T_EQUIPDSCMML T
|
||
where T.PRN = NEQUIPDSCM
|
||
order by T.RN)
|
||
loop
|
||
/* Добавляем колонки с данными */
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'STASK', SVALUE => C.STASK);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPRECISION_P', NVALUE => C.NPRECISION_P);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPRECISION_F', NVALUE => C.NPRECISION_F);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSTATUS', NVALUE => C.NSTATUS);
|
||
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SERR', SVALUE => C.SERR);
|
||
/* Добавляем строку в таблицу */
|
||
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||
end loop;
|
||
/* Сериализуем описание */
|
||
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
||
end CMML_LIST;
|
||
|
||
/* Код доступного действия с моделью по единице оборудования */
|
||
function CMML_ACT_BY_EQCONFIG
|
||
(
|
||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||
) return number -- Код действия с моделью (0 - нет доступных, 1 - запросить прогноз, 2 - обучить)
|
||
is
|
||
begin
|
||
return 2;
|
||
end CMML_ACT_BY_EQCONFIG;
|
||
|
||
/* Список моделей по единице оборудования */
|
||
function CMML_LIST_BY_EQCONFIG
|
||
(
|
||
NEQCONFIG in number -- Рег. номер позиции состава оборудования
|
||
) return varchar2 -- Список моделей с системным разделителем по умолчанию
|
||
is
|
||
begin
|
||
return 'TCF;RUL;FP';
|
||
end CMML_LIST_BY_EQCONFIG;
|
||
|
||
end UDO_PKG_EQUIPDS;
|
||
/
|