96f33c01ee
Files correlati : ve6.exe Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 979 git-svn-id: svn://10.65.10.50/trunk@15623 c028cbd2-c16b-5b4b-a496-9718f37d4682
626 lines
17 KiB
C++
Executable File
626 lines
17 KiB
C++
Executable File
// quadb_b1.cpp
|
||
#include <relapp.h>
|
||
#include <urldefid.h>
|
||
|
||
#include "dipend.h"
|
||
#include "774200.h"
|
||
#include "77lib.h"
|
||
#include "quadrob.h"
|
||
#include "quadrob1.h"
|
||
#include "77qb.h"
|
||
#include "77qb1.h"
|
||
|
||
class TQuadriBB1_application : public TRelation_application
|
||
{
|
||
static bool codditta77_handler (TMask_field& m, KEY k);
|
||
static bool PrimoNprogLibero (TMask& m, const long codditta, const long coddip);
|
||
static bool CodDipHandler (TMask_field& m, KEY k);
|
||
static bool NprogExitHandler (TMask_field& m, KEY k);
|
||
static bool QBTotRedImpHandler (TMask_field& f, KEY k);
|
||
static bool QBAmmRopeHandler (TMask_field& f, KEY k);
|
||
static bool QBTotIndennHandler (TMask_field& f, KEY k);
|
||
static bool QBCalcola37 (TMask_field& f, KEY k);
|
||
static void BB1SettaCognomeNome(TMask& m);
|
||
const char* _maskname;
|
||
int _num;
|
||
int _pos_quadro; // posizione nell'array dei quadri. Usato in set_comp
|
||
TString16 _quadro;
|
||
TRiporti _rip;
|
||
TRelation* _rel;
|
||
TMask* _msk[2];
|
||
bool _registra;
|
||
int _anno_dic;
|
||
int _mode;
|
||
bool _MaskConAnnoDic, _MaskConCodditta;
|
||
bool MaskConAnnoDic() const;
|
||
bool MaskConCodditta() const { return _MaskConCodditta; }
|
||
bool QuadroB() const { return _num == LF_QUAB; }
|
||
bool QuadroB1() const { return _num == LF_QUAB1; }
|
||
bool CheckImporti(const TMask& m);
|
||
bool EsisteGiaCodDip(const TMask& m);
|
||
bool EsisteGiaRecordDip(const TMask& m);
|
||
long _codditta;
|
||
long _lCodDip;
|
||
int _iNprog;
|
||
TString _sCognome, _sNome;
|
||
void init_mask(TMask&);
|
||
|
||
protected:
|
||
virtual bool user_create();
|
||
virtual bool user_destroy();
|
||
// virtual int read(TMask& m);
|
||
virtual int rewrite(const TMask& m);
|
||
virtual int write (const TMask& m);
|
||
virtual bool remove();
|
||
virtual void on_config_change();
|
||
virtual TMask* get_mask(int);
|
||
virtual bool changing_mask(int);
|
||
TMask* load_mask(int n);
|
||
virtual TRelation* get_relation() const { return _rel; }
|
||
virtual void init_query_mode(TMask&);
|
||
virtual void init_query_insert_mode(TMask&);
|
||
virtual void init_insert_mode(TMask&);
|
||
virtual void init_modify_mode(TMask&);
|
||
|
||
public:
|
||
TQuadriBB1_application(const char* name, const int num, const char* quadro);
|
||
};
|
||
|
||
TQuadriBB1_application::TQuadriBB1_application(const char* name, const int num, const char* quadro)
|
||
: _maskname(name), _num(num), _mode(0),
|
||
_MaskConCodditta(FALSE), _MaskConAnnoDic(FALSE),
|
||
_rel(NULL), _quadro(quadro)
|
||
{
|
||
memset(_msk, 0, sizeof(_msk));
|
||
switch (_num)
|
||
{
|
||
case LF_QUAB:
|
||
_pos_quadro = B;
|
||
break;
|
||
case LF_QUAB1:
|
||
_pos_quadro = B1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
TQuadriBB1_application& app() { return (TQuadriBB1_application&)main_app(); }
|
||
|
||
bool TQuadriBB1_application::changing_mask(int mode)
|
||
{
|
||
if ((mode == MODE_MOD) && (_mode == MODE_INS))
|
||
return FALSE;
|
||
else
|
||
return _mode != mode;
|
||
}
|
||
|
||
TMask* TQuadriBB1_application::get_mask(int mode)
|
||
{
|
||
const int m = (mode == MODE_QUERY) ? 0 : 1;
|
||
_mode = mode;
|
||
return load_mask(m);
|
||
}
|
||
|
||
TMask* TQuadriBB1_application::load_mask(int n)
|
||
{
|
||
if (_msk[n] != NULL)
|
||
return _msk[n];
|
||
|
||
TFilename name("77qb");
|
||
|
||
if (n == 0)
|
||
{
|
||
switch (_num)
|
||
{
|
||
case LF_QUAB:
|
||
name << 'a';
|
||
break;
|
||
case LF_QUAB1:
|
||
name << "1a";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
switch (_num)
|
||
{
|
||
case LF_QUAB:
|
||
name << 'b';
|
||
break;
|
||
case LF_QUAB1:
|
||
name << "1b";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
TMask* m = new TMask(name);
|
||
m->set_handler(CODDITTA77, codditta77_handler);
|
||
|
||
switch (n)
|
||
{
|
||
case 0:
|
||
if (QuadroB())
|
||
{
|
||
m->set_handler(QBF_CODDIP_QB, CodDipHandler);
|
||
m->set_handler(QBF_CODDIP_ANAG, CodDipHandler);
|
||
set_search_field(QBF_NPROG);
|
||
}
|
||
else
|
||
{
|
||
m->set_handler(QB1F_CODDIP_QB1, CodDipHandler);
|
||
m->set_handler(QB1F_CODDIP_ANAG, CodDipHandler);
|
||
set_search_field(QB1F_NPROG);
|
||
}
|
||
m->set_handler(QuadroB() ? QBF_NPROG : QB1F_NPROG, NprogExitHandler);
|
||
break;
|
||
case 1:
|
||
if (m)
|
||
if (QuadroB())
|
||
{
|
||
m->set_handler(QBF_TOTIMP, QBTotRedImpHandler);
|
||
m->set_handler(QBF_ROPE, QBAmmRopeHandler);
|
||
m->set_handler(QBF_AMMNETTO, QBTotIndennHandler);
|
||
m->set_handler(QBF_AMMNETTO2, QBTotIndennHandler);
|
||
m->set_handler(QBF_CONTLAV, QBTotIndennHandler);
|
||
m->set_handler(QBF_TFR7494, QBTotIndennHandler);
|
||
m->set_handler(QBF_INDEN7494, QBTotIndennHandler);
|
||
m->set_handler(QBF_TIND7494, QBCalcola37); // 28
|
||
m->set_handler(QBF_TRID, QBCalcola37); // 29
|
||
}
|
||
m->disable(DLG_FINDREC);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return _msk[n] = m;
|
||
}
|
||
|
||
bool TQuadriBB1_application::QBCalcola37(TMask_field& f, KEY k)
|
||
{
|
||
TMask& m=f.mask();
|
||
if (k==K_TAB && m.is_running())
|
||
{
|
||
real c28=m.get_real(QBF_TIND7494);
|
||
real c29=m.get_real(QBF_TRID);
|
||
real c37 = c28 - c29;
|
||
if (c37 < ZERO)
|
||
c37 = ZERO;
|
||
TString c37s(c37.string());
|
||
m.set(QBF_TOTIMP,c37s);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TQuadriBB1_application::MaskConAnnoDic() const
|
||
{
|
||
return _MaskConAnnoDic;
|
||
}
|
||
|
||
void TQuadriBB1_application::on_config_change()
|
||
{
|
||
TConfig conf(CONFIG_STUDIO);
|
||
_anno_dic = (int)conf.get_long(ANNO_SEL, NULL, -1, TDate(TODAY).year());
|
||
}
|
||
|
||
bool TQuadriBB1_application::user_create()
|
||
{
|
||
_registra = FALSE;
|
||
_rel = new TRelation(_num);
|
||
_codditta = get_firm_770();
|
||
return TRUE;
|
||
}
|
||
|
||
bool TQuadriBB1_application::user_destroy()
|
||
{
|
||
if (_quadro != "")
|
||
if (_registra)
|
||
_rip.set(_quadro);
|
||
if (_msk[1] != NULL) delete _msk[1];
|
||
if (_msk[0] != NULL) delete _msk[0];
|
||
delete _rel;
|
||
return TRUE;
|
||
}
|
||
|
||
// Q.B. Controlla che ci sia diverso da ZERO il tot.red.imp.
|
||
bool TQuadriBB1_application::CheckImporti(const TMask& m)
|
||
{
|
||
real TotRedImp(m.get(QBF_TOTIMP));
|
||
return TotRedImp != ZERO;
|
||
}
|
||
|
||
// Controlla se esiste gia' un record con lo stesso cod.dip.
|
||
bool TQuadriBB1_application::EsisteGiaCodDip(const TMask& m)
|
||
{
|
||
TLocalisamfile q(_num);
|
||
const long codip = m.get_long(QuadroB()? QBF_CODDIP : QB1F_CODDIP);
|
||
q.zero();
|
||
q.put(QB_CODDITTA, _codditta);
|
||
q.put(QB_CODDIP, codip);
|
||
TRectype dep(q.curr());
|
||
q.read(_isgteq);
|
||
const bool bEq = q.curr() == dep;
|
||
return bEq;
|
||
}
|
||
|
||
// Controlla se esiste gia' una chiave completa
|
||
bool TQuadriBB1_application::EsisteGiaRecordDip(const TMask& m)
|
||
{
|
||
TLocalisamfile q(_num);
|
||
const long codip = m.get_long(QuadroB()? QBF_CODDIP : QB1F_CODDIP);
|
||
const long nprog = m.get_long(QuadroB()? QBF_NPROG : QB1F_NPROG);
|
||
q.zero();
|
||
q.put(QB_CODDITTA, _codditta);
|
||
q.put(QB_CODDIP, codip);
|
||
q.put(QB_NPROG, nprog);
|
||
TRectype dep(q.curr());
|
||
const bool bEq = q.read() == NOERR;
|
||
return bEq;
|
||
}
|
||
|
||
int TQuadriBB1_application::rewrite(const TMask& m)
|
||
{
|
||
m.autosave(*_rel);
|
||
const int err = _rel->rewrite();
|
||
_registra = err == NOERR;
|
||
return err;
|
||
}
|
||
|
||
/*
|
||
int TQuadriBB1_application::read(TMask& m)
|
||
{
|
||
int err;
|
||
_rel->lfile().put("CODDITTA", (long)_codditta);
|
||
_rel->lfile().put("CODDIP", (long)_lCodDip);
|
||
_rel->lfile().put("NPROG", _iNprog);
|
||
err = _rel->read();
|
||
return err;
|
||
}
|
||
*/
|
||
|
||
int TQuadriBB1_application::write(const TMask& m)
|
||
{
|
||
m.autosave(*_rel);
|
||
if (QuadroB1())
|
||
if (EsisteGiaRecordDip(m))
|
||
return warning_box("E' gi<67> presente un record per questo dipendente");
|
||
const int err = _rel->write();
|
||
_registra = err == NOERR;
|
||
return err;
|
||
}
|
||
|
||
bool TQuadriBB1_application::remove()
|
||
{
|
||
_registra = TRUE;
|
||
return TRelation_application::remove();
|
||
}
|
||
|
||
void TQuadriBB1_application::init_mask(TMask& m)
|
||
{
|
||
if (QuadroB())
|
||
{
|
||
// leggi dalla maschera di query, che' dovrebbero li' esservi sempre..
|
||
const long codditta = _msk[0]->get_long(QBF_CODDITTA);
|
||
const long codip = _msk[0]->get_long(QBF_CODDIP);
|
||
if (codip==0L)
|
||
return;
|
||
if (is_erede(codditta,codip)) // && modifica(m))
|
||
{
|
||
m.disable(-GROUP_ALL);
|
||
m.enable(-GROUP_EREDE);
|
||
}
|
||
else
|
||
{
|
||
m.enable(-GROUP_ALL);
|
||
if (is_deceduto(codditta,codip) || is_dipendente(codditta,codip))
|
||
m.disable(-GROUP_DIPDEC);
|
||
else
|
||
m.enable(-GROUP_DIPDEC);
|
||
}
|
||
}
|
||
}
|
||
|
||
void TQuadriBB1_application::init_modify_mode(TMask& m)
|
||
{
|
||
init_mask(m);
|
||
/*
|
||
if (QuadroB())
|
||
{
|
||
m.set(QBF_CODDIP, _lCodDip);
|
||
m.set(QBF_COGNOME, _sCognome);
|
||
m.set(QBF_NOME, _sNome);
|
||
m.set(QBF_NPROG, _iNprog);
|
||
}
|
||
else
|
||
{
|
||
m.set(QB1F_CODDIP, _lCodDip);
|
||
m.set(QB1F_COGNOME, _sCognome);
|
||
m.set(QB1F_NOME, _sNome);
|
||
m.set(QB1F_NPROG, _iNprog);
|
||
}*/
|
||
}
|
||
|
||
void TQuadriBB1_application::init_insert_mode(TMask& m)
|
||
{
|
||
init_mask(m);
|
||
}
|
||
|
||
void TQuadriBB1_application::init_query_mode(TMask& m)
|
||
{
|
||
m.set(ANNODIC77, _anno_dic);
|
||
if (QuadroB())
|
||
{
|
||
m.show(-QBG_QUADROB);
|
||
m.hide(-QBG_ANADIP);
|
||
}
|
||
else
|
||
{
|
||
m.show(-QB1G_QUADROB);
|
||
m.hide(-QB1G_ANADIP);
|
||
}
|
||
}
|
||
|
||
void TQuadriBB1_application::init_query_insert_mode(TMask& m)
|
||
{
|
||
m.set(ANNODIC77, _anno_dic);
|
||
if (QuadroB())
|
||
{
|
||
m.hide(-QBG_QUADROB);
|
||
m.show(-QBG_ANADIP);
|
||
}
|
||
else
|
||
{
|
||
m.hide(-QB1G_QUADROB);
|
||
m.show(-QB1G_ANADIP);
|
||
}
|
||
}
|
||
|
||
bool TQuadriBB1_application::codditta77_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_TAB)
|
||
{
|
||
TMask& m = f.mask();
|
||
TString16 codditta; codditta << app()._codditta;
|
||
if (codditta != "0")
|
||
{
|
||
m.set(CODDITTA77, codditta);
|
||
m.field(CODDITTA77).check();
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 2 modi :
|
||
// RUN,773,-1,771230m,89,"Prospetto del Quadro E1","E1" [771230i.uml]
|
||
// oppure
|
||
// 773 -1 menu_st "Stampe dichiarazioni" [prassi.mnu]
|
||
// QUADRO N:
|
||
// 773,-2,77qn,72,"Quadro N","N"
|
||
///////////////////////////////////////////////////////////
|
||
int quadriB_B1(int argc, char* argv[])
|
||
{
|
||
TFilename mask;
|
||
int num = 0;
|
||
if (argc > 1)
|
||
mask = argv[2];
|
||
num = atoi(argv[3]);
|
||
const char* title = argv[4];
|
||
const char* quadro = argv[5];
|
||
TQuadriBB1_application a(mask, num, quadro);
|
||
a.run(argc, argv, title ? title : "Test Relation Application");
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// CodDipHandler
|
||
//
|
||
// 1 - Controlla che il codice dipendente esista
|
||
// 2 - Propone il primo progressivo disponibile per quel codice
|
||
//
|
||
bool TQuadriBB1_application::CodDipHandler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (!m.is_running()) return TRUE;
|
||
|
||
if (k == K_ENTER)
|
||
{
|
||
const long codip = atol(f.get());
|
||
if (codip==0L)
|
||
return TRUE;
|
||
|
||
if (!esiste_dipendente(app()._codditta, codip))
|
||
return f.warning_box("Dipendente inesistente");
|
||
}
|
||
|
||
if (k == K_TAB)
|
||
{
|
||
const long codip = atol(f.get());
|
||
if (codip==0L)
|
||
return TRUE;
|
||
|
||
if (!esiste_dipendente(app()._codditta, codip))
|
||
return f.warning_box("Dipendente inesistente");
|
||
|
||
PrimoNprogLibero(m, app()._codditta, codip);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Compila cognome e nome se vuoti
|
||
void TQuadriBB1_application::BB1SettaCognomeNome(TMask& m)
|
||
{
|
||
const int iDlgCognome = app().QuadroB() ? QBF_COGNOME : QB1F_COGNOME;
|
||
const int iDlgNome = app().QuadroB() ? QBF_NOME : QB1F_NOME;
|
||
const int iDlgNProg = app().QuadroB() ? QBF_NPROG : QB1F_NPROG;
|
||
const int iProg = m.get_int(iDlgNProg);
|
||
TString sCognome(m.get(iDlgCognome));
|
||
TString sNome;
|
||
if (app()._lCodDip != 0L)
|
||
{
|
||
TLocalisamfile dip (LF_DIPEND);
|
||
dip.zero();
|
||
dip.put(DIP_CODDITTA, app()._codditta);
|
||
dip.put(DIP_CODIP, app()._lCodDip);
|
||
if (dip.read() == NOERR)
|
||
{
|
||
sCognome = dip.get("COGNOME");
|
||
sNome = dip.get("NOME");
|
||
app()._sCognome = sCognome;
|
||
app()._sNome = sNome;
|
||
app()._iNprog = iProg;
|
||
m.set(iDlgCognome, sCognome);
|
||
m.set(iDlgNome, sNome);
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TQuadriBB1_application::NprogExitHandler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (!m.is_running()) return TRUE;
|
||
|
||
if (k == K_CTRL+K_TAB)
|
||
{
|
||
f.set_dirty();
|
||
return TRUE;
|
||
}
|
||
|
||
if (k == K_TAB)
|
||
{
|
||
TString nprog(f.get());
|
||
if (nprog.not_empty())
|
||
{
|
||
const int ID_CODDIP = app().QuadroB()? QBF_CODDIP : QB1F_CODDIP;
|
||
const long codip = app()._lCodDip = m.get_long(ID_CODDIP);
|
||
const long codditta = app()._codditta;
|
||
// const long codip = m.get_long(ID_CODDIP);
|
||
// const long codditta = app()._codditta;
|
||
|
||
if (codip==0L)
|
||
return TRUE;
|
||
|
||
// Nel B1 e nel B (per gli eredi) pu<70> esserci un solo record per dipendente
|
||
if (app().QuadroB1() || (app().QuadroB() && is_erede(codditta,codip)) )
|
||
// Se esiste gia' un record per questo dipendente MA NON la chiave completa
|
||
// (ora presente nella maschera) rifiuta il record
|
||
// (impedisce cioe' di andare in inserimento, a meno che non sia la prima
|
||
// volta, cioe' a meno che non esista ancora nessun record per il dip.
|
||
// (questo caso e' segnalato dal fallimento della EsisteGiaCodDip) )
|
||
if (app().EsisteGiaCodDip(m) && !app().EsisteGiaRecordDip(m))
|
||
return f.warning_box("Esiste gi<67> una riga per questo dipendente");
|
||
|
||
// Compila cognome e nome se vuoti
|
||
BB1SettaCognomeNome(m);
|
||
// m.stop_run(K_AUTO_ENTER);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TQuadriBB1_application::PrimoNprogLibero(TMask& m, const long codditta, const long codip)
|
||
{
|
||
// Propone il primo numero disponibile
|
||
if (codip != 0L)
|
||
{
|
||
long nprog = 0L;
|
||
const int id_nprog = app().QuadroB() ? QBF_NPROG : QB1F_NPROG;
|
||
const bool erede = is_erede(codditta,codip);
|
||
bool EsisteGiaDip = FALSE;
|
||
TLocalisamfile qb(app()._num);
|
||
qb.zero();
|
||
qb.put(QB_CODDITTA, codditta);
|
||
qb.put(QB_CODDIP, codip);
|
||
TRectype dep(qb.curr());
|
||
qb.read(_isgteq);
|
||
TRecnotype lPosPrec = qb.recno();
|
||
for ( ; !qb.eof(); qb.next())
|
||
{
|
||
if (qb.curr() > dep) break;
|
||
EsisteGiaDip = TRUE;
|
||
nprog = qb.get_long(QB_NPROG);
|
||
}
|
||
qb.readat(lPosPrec);
|
||
|
||
// Nel B se e' un erede si puo' solo andare in modifica
|
||
// Nel B1 <20> consentito un solo record per dipendente
|
||
if ( (nprog == 0) || (app().QuadroB1() && !EsisteGiaDip) ||
|
||
(app().QuadroB() && !erede) )
|
||
nprog++;
|
||
|
||
TString16 nprog_str; nprog_str << nprog;
|
||
m.set(id_nprog, nprog_str);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////
|
||
// QUADRO B
|
||
///////////////////////////////////////////////////////////////////////////////////
|
||
bool TQuadriBB1_application::QBTotRedImpHandler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (k == K_ENTER && !ricerca(m))
|
||
{
|
||
const long codditta = m.get_long(QBF_CODDITTA);
|
||
const long codip = m.get_long(QBF_CODDIP);
|
||
if (!is_erede(codditta,codip))
|
||
{
|
||
real totimp(f.get());
|
||
if (totimp == ZERO)
|
||
return f.warning_box("Il totale reddito imponibile non pu<70> essere nullo");
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TQuadriBB1_application::QBAmmRopeHandler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (k == K_ENTER && !ricerca(m))
|
||
{
|
||
TMask& m = f.mask();
|
||
const long codditta = m.get_long(QBF_CODDITTA);
|
||
const long codip = m.get_long(QBF_CODDIP);
|
||
if (!is_erede(codditta,codip))
|
||
{
|
||
real totimp(m.get(QBF_TOTIMP));
|
||
real rope(f.get());
|
||
if (rope > totimp)
|
||
return f.warning_box("Il totale ritenute non pu<70> essere maggiore del totale reddito imponibile");
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// 23.5.96 Calcola totale indennit<69>
|
||
bool TQuadriBB1_application::QBTotIndennHandler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_TAB)
|
||
{
|
||
const bool ricalcola = f.focusdirty();
|
||
if (ricalcola)
|
||
{
|
||
TMask& m = f.mask();
|
||
real c20 = m.get_real(QBF_AMMNETTO);
|
||
real c24 = m.get_real(QBF_AMMNETTO2);
|
||
real c25 = m.get_real(QBF_CONTLAV);
|
||
real c26 = m.get_real(QBF_TFR7494);
|
||
real c27 = m.get_real(QBF_INDEN7494);
|
||
|
||
real c28 = c20 + c24 - c25 + c26 + c27;
|
||
if (c28 < ZERO)
|
||
c28 = ZERO;
|
||
TString c28s(c28.string());
|
||
m.set(QBF_TIND7494, c28s);
|
||
// Ricalcola il 37 da qui perche' il 28 e' disabilitato
|
||
QBCalcola37(f,k);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|