517 lines
20 KiB
JavaScript
517 lines
20 KiB
JavaScript
/* -------------------------------------------- */
|
|
import { RdDCalendrierEditeur } from "./rdd-calendrier-editeur.js";
|
|
import { RdDAstrologieEditeur } from "./rdd-astrologie-editeur.js";
|
|
import { HtmlUtility } from "./html-utility.js";
|
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
|
import { RdDUtility } from "./rdd-utility.js";
|
|
|
|
/* -------------------------------------------- */
|
|
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
|
|
const heuresList = [ "vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant" ];
|
|
const heuresDef = { "vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' },
|
|
"sirene": { label: "Sirène", lettreFont: 'S', saison: "printemps", heure: 1, icon: 'hd02.svg' },
|
|
"faucon": { label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' },
|
|
"couronne": { label: "Couronne", lettreFont: 'C', saison: "ete", heure: 3, icon: 'hd04.svg' },
|
|
"dragon": { label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' },
|
|
"epees": { label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' },
|
|
"lyre": { label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' },
|
|
"serpent": { label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' },
|
|
"poissonacrobate": { label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' },
|
|
"araignee": { label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' },
|
|
"roseau": { label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' },
|
|
"chateaudormant": { label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' }
|
|
};
|
|
const saisonsDef = { "printemps": { label: "Printemps"},
|
|
"ete": { label: "Eté"},
|
|
"automne": { label: "Automne"},
|
|
"hiver": { label: "Hiver"}
|
|
};
|
|
const RDD_JOUR_PAR_MOIS = 28;
|
|
const MAX_NOMBRE_ASTRAL = 12;
|
|
|
|
/* -------------------------------------------- */
|
|
export class RdDCalendrier extends Application {
|
|
|
|
/* -------------------------------------------- */
|
|
async initCalendrier() {
|
|
// Calendrier
|
|
this.calendrier = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier"));
|
|
console.log("CALENDRIER", this.calendrier);
|
|
if ( this.calendrier == undefined || this.calendrier.moisRdD == undefined) {
|
|
this.calendrier.heureRdD = 0; // Index dans heuresList
|
|
this.calendrier.heuresRelative = 0;
|
|
this.calendrier.minutesRelative = 0;
|
|
this.calendrier.moisRdD = 0; // Index dans heuresList
|
|
this.calendrier.jour = 0;
|
|
if ( game.user.isGM) { // Uniquement si GM
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier", this.calendrier );
|
|
}
|
|
}
|
|
// position
|
|
this.calendrierPos = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier-pos"));
|
|
if ( this.calendrierPos == undefined || this.calendrierPos.top == undefined) {
|
|
this.calendrierPos.top = 200;
|
|
this.calendrierPos.left = 200;
|
|
if ( game.user.isGM) { // Uniquement si GM
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", this.calendrierPos );
|
|
}
|
|
}
|
|
// nombre astral
|
|
if ( game.user.isGM) {
|
|
this.listeNombreAstral = this._loadListNombreAstral();
|
|
this.rebuildListeNombreAstral(); // Ensure always up-to-date
|
|
}
|
|
console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
_loadListNombreAstral() {
|
|
return Object.values(game.settings.get("foundryvtt-reve-de-dragon", "liste-nombre-astral"));
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static get defaultOptions() {
|
|
const options = super.defaultOptions;
|
|
options.template = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
|
|
options.popOut = false;
|
|
options.resizable = false;
|
|
return options;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getDateFromIndex( index ) {
|
|
let month = Math.floor(index / 28);
|
|
let day = (index - (month*28)) + 1;
|
|
return day+" "+heuresList[month];
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getCurrentDayIndex( ) {
|
|
return (this.calendrier.moisRdD * 28) + this.calendrier.jour;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getJoursSuivants( num) {
|
|
let jours = [];
|
|
let index = this.getCurrentDayIndex();
|
|
for (let i=0; i<num; i++) {
|
|
jours[i] = { label: this.getDateFromIndex(index), index: index };
|
|
index += 1;
|
|
}
|
|
return jours;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
ajouterNombreAstral(index) {
|
|
return {
|
|
nombreAstral: new Roll("1d12").roll().total,
|
|
valeursFausses: [],
|
|
index: index
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getCurrentNombreAstral() {
|
|
let index = this.getCurrentDayIndex();
|
|
return this.getNombreAstral(index);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getNombreAstral( index ) {
|
|
const liste = this.listeNombreAstral || this._loadListNombreAstral();
|
|
let astralData = liste.find( (nombreAstral, i) => nombreAstral.index == index );
|
|
if ( astralData == undefined ) {
|
|
this.rebuildListeNombreAstral();
|
|
astralData = liste.find( (nombreAstral, i) => nombreAstral.index == index );
|
|
}
|
|
return astralData.nombreAstral || "N/A";
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
rebuildListeNombreAstral() {
|
|
// Auto-create if needed
|
|
if ( this.listeNombreAstral == undefined)
|
|
this.listeNombreAstral = [];
|
|
|
|
// Nettoyage des nombres astraux anciens
|
|
let jourCourant = this.getCurrentDayIndex();
|
|
let jourFin = jourCourant + 12;
|
|
let newList = this.listeNombreAstral.filter( (nombreAstral, i) => nombreAstral && nombreAstral.index >= jourCourant && nombreAstral.index < jourFin);
|
|
//console.log("LSTES", this.listeNombreAstral, newList );
|
|
|
|
let lastDay = jourCourant;
|
|
for (let i=0; i < MAX_NOMBRE_ASTRAL; i++) {
|
|
let nombreAstral = newList[i];
|
|
if ( nombreAstral ) {
|
|
lastDay = nombreAstral.index + 1;
|
|
} else {
|
|
newList.push( this.ajouterNombreAstral( lastDay) );
|
|
lastDay += 1;
|
|
}
|
|
}
|
|
this.listeNombreAstral = newList;
|
|
|
|
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral );
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
incrementTime(heure, minute = 0) {
|
|
this.calendrier.minutesRelative += minute;
|
|
if (this.calendrier.minutesRelative >= 60 ) {
|
|
this.calendrier.minutesRelative -= 60;
|
|
heure += 1;
|
|
}
|
|
this.calendrier.heuresRelative += heure;
|
|
if (this.calendrier.heuresRelative >= 2) {
|
|
this.calendrier.heuresRelative -= 2;
|
|
this.calendrier.heureRdD += 1;
|
|
}
|
|
if ( this.calendrier.heureRdD > 11 ) {
|
|
this.calendrier.heureRdD -= 12;
|
|
this.incrementerJour();
|
|
}
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) );
|
|
// Notification aux joueurs
|
|
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
|
msg: "msg_sync_time",
|
|
data: duplicate(this.calendrier)
|
|
} );
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
incrementerJour( ) {
|
|
this.calendrier.jour += 1;
|
|
if ( this.calendrier.jour >= RDD_JOUR_PAR_MOIS) {
|
|
this.calendrier.jour -= RDD_JOUR_PAR_MOIS;
|
|
if ( this.calendrier.jour <= 0)
|
|
this.calendrier.jour = 0;
|
|
this.calendrier.moisRdD += 1;
|
|
// Reconstruire les nombres astraux
|
|
}
|
|
this.rebuildListeNombreAstral();
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
syncPlayerTime( calendrier ) {
|
|
this.calendrier = duplicate(calendrier); // Local copy update
|
|
this.updateDisplay(); // Then update
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
positionnerHeure( indexHeure ) {
|
|
if ( indexHeure <= this.calendrier.heureRdD )
|
|
this.incrementerJour();
|
|
this.calendrier.heureRdD = indexHeure;
|
|
this.calendrier.minutesRelative = 0;
|
|
this.calendrier.heuresRelative = 0;
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) );
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
fillCalendrierData( data = {} ) {
|
|
let moisKey = heuresList[this.calendrier.moisRdD];
|
|
let heureKey = heuresList[this.calendrier.heureRdD];
|
|
|
|
const mois = heuresDef[moisKey];
|
|
const heure = heuresDef[heureKey];
|
|
|
|
//console.log(moisKey, heureKey);
|
|
data.heureKey = heureKey;
|
|
data.moisKey = moisKey;
|
|
data.jourMois = this.calendrier.jour + 1;
|
|
data.nomMois = mois.label; // heures et mois nommés identiques
|
|
data.iconMois = dossierIconesHeures + mois.icon;
|
|
data.nomHeure = heure.label;
|
|
data.iconHeure = dossierIconesHeures + heure.icon;
|
|
data.nomSaison = saisonsDef[mois.saison].label;
|
|
data.heuresRelative = this.calendrier.heuresRelative;
|
|
data.minutesRelative = this.calendrier.minutesRelative;
|
|
data.isGM = game.user.isGM;
|
|
return data;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getLectureAstrologieDifficulte( dateIndex ) {
|
|
let indexNow = this.getCurrentDayIndex();
|
|
let diffDay = dateIndex - indexNow;
|
|
return - Math.floor(diffDay / 2);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async requestNombreAstral( request) {
|
|
if ( game.user.isGM) { // Only GM
|
|
console.log( request );
|
|
let jourDiff = this.getLectureAstrologieDifficulte( request.date);
|
|
let niveau = Number(request.astrologie.data.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat);
|
|
let rolled = await RdDResolutionTable.rollData({
|
|
caracValue: request.carac_vue,
|
|
finalLevel: niveau,
|
|
showDice: false});
|
|
let nbAstral = this.getNombreAstral( request.date );
|
|
let nbAstralFaux = nbAstral;
|
|
request.isValid = true;
|
|
request.rolled = rolled;
|
|
if ( !rolled .isSuccess ) {
|
|
request.isValid = false;
|
|
while ( nbAstralFaux == nbAstral ) {
|
|
nbAstralFaux = new Roll("1d12").roll().total;
|
|
}
|
|
nbAstral = nbAstralFaux;
|
|
// Mise à jour des nombres astraux du joueur
|
|
let astralData = this.listeNombreAstral.find( (nombreAstral, i) => nombreAstral.index == request.date );
|
|
astralData.valeursFausses.push( {actorId: request.id, nombreAstral: nbAstralFaux});
|
|
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral );
|
|
}
|
|
request.nbAstral = nbAstral;
|
|
if ( game.user.isGM) {
|
|
RdDUtility.responseNombreAstral( request );
|
|
} else {
|
|
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
|
msg: "msg_response_nombre_astral",
|
|
data: request
|
|
} );
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getAjustementAstrologique(heureNaissance, name='inconnu')
|
|
{
|
|
if (heureNaissance && heuresDef[heureNaissance]) {
|
|
let hn = heuresDef[heureNaissance].heure;
|
|
let chiffreAstral = this.getCurrentNombreAstral();
|
|
let heureCourante = this.calendrier.heureRdD;
|
|
let ecartChance = (hn + chiffreAstral - heureCourante)%12;
|
|
switch (ecartChance)
|
|
{
|
|
case 0: return 4;
|
|
case 4: case 8: return 2;
|
|
case 6: return -4;
|
|
case 3: case 9: return -2;
|
|
}
|
|
}
|
|
else {
|
|
ui.notifications.warn(this.data.name + " n'a pas d'heure de naissance, ou elle est incorrecte");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getData() {
|
|
let data = super.getData();
|
|
|
|
this.fillCalendrierData(data);
|
|
|
|
this.setPos( this.calendrierPos );
|
|
return data;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
setPos(pos) {
|
|
return new Promise(resolve => {
|
|
function check() {
|
|
let elmnt = document.getElementById("calendar-time-container");
|
|
if (elmnt) {
|
|
elmnt.style.bottom = null;
|
|
let xPos = (pos.left) > window.innerWidth ? window.innerWidth-200 : pos.left;
|
|
let yPos = (pos.top) > window.innerHeight-20 ? window.innerHeight-100 : pos.top;
|
|
elmnt.style.top = (yPos) + "px";
|
|
elmnt.style.left = (xPos) + "px";
|
|
elmnt.style.position = 'fixed';
|
|
elmnt.style.zIndex = 100;
|
|
resolve();
|
|
} else {
|
|
setTimeout(check, 30);
|
|
}
|
|
}
|
|
check();
|
|
});
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
updateDisplay() {
|
|
let data = this.fillCalendrierData( );
|
|
// Rebuild data
|
|
document.getElementById("calendar--move-handle").innerHTML = `Jour ${data.jourMois} de ${data.nomMois} (${data.nomSaison})` + " - NA: "+this.getCurrentNombreAstral();
|
|
document.getElementById("calendar-heure-texte").innerHTML = `${data.nomHeure}`;
|
|
document.getElementById("calendar-time").innerHTML = `${data.heuresRelative}:${data.minutesRelative}`;
|
|
document.getElementById("calendar-heure-img").src = data.iconHeure;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
saveEditeur( calendrierData ) {
|
|
this.calendrier.heuresRelative = Number(calendrierData.heuresRelative);
|
|
this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
|
|
this.calendrier.jour = Number(calendrierData.jourMois) - 1;
|
|
this.calendrier.moisRdD = heuresList.findIndex(mois => mois === calendrierData.moisKey);
|
|
this.calendrier.heureRdD = heuresList.findIndex(heure => heure === calendrierData.heureKey);; // Index dans heuresList
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) );
|
|
|
|
this.rebuildListeNombreAstral();
|
|
|
|
this.updateDisplay();
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async showCalendarEditor() {
|
|
let calendrierData = duplicate( this.fillCalendrierData( ) );
|
|
if ( this.editeur == undefined ) {
|
|
calendrierData.jourMoisOptions = Array(28).fill().map((item, index) => 1 + index);
|
|
calendrierData.heuresOptions = [0, 1];
|
|
calendrierData.minutesOptions = Array(60).fill().map((item, index) => 0 + index);
|
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', calendrierData );
|
|
this.editeur = new RdDCalendrierEditeur(html, this, calendrierData )
|
|
}
|
|
this.editeur.updateData( calendrierData );
|
|
this.editeur.render(true);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async showAstrologieEditor() {
|
|
let calendrierData = duplicate( this.fillCalendrierData( ) );
|
|
let astrologieArray = [];
|
|
for (let astralData of this.listeNombreAstral ) {
|
|
astralData.humanDate = this.getDateFromIndex( astralData.index );
|
|
for (let vf of astralData.valeursFausses) {
|
|
let actor = game.actors.get( vf.actorId);
|
|
console.log(vf.actorId, actor );
|
|
vf.actorName = (actor) ? actor.name : "Inconnu";
|
|
}
|
|
astrologieArray.push( duplicate(astralData ) );
|
|
}
|
|
//console.log("ASTRO", astrologieArray);
|
|
calendrierData.astrologieData = astrologieArray;
|
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-astrologie-template.html', calendrierData );
|
|
let astrologieEditeur = new RdDAstrologieEditeur(html, this, calendrierData )
|
|
astrologieEditeur.updateData( calendrierData );
|
|
astrologieEditeur.render(true);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
/** @override */
|
|
activateListeners(html) {
|
|
super.activateListeners(html);
|
|
|
|
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
|
|
|
|
this.updateDisplay();
|
|
|
|
html.find('#calendar-btn-1min').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(0, 1);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-5min').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(0, 5);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-10min').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(0, 10);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-20min').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(0, 20);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-30min').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(0, 30);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-1heure').click(ev => {
|
|
ev.preventDefault();
|
|
this.incrementTime(2, 0);
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-vaisseau').click(ev => {
|
|
ev.preventDefault();
|
|
this.positionnerHeure(0); // 0 -> vaisseau
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-lyre').click(ev => {
|
|
ev.preventDefault();
|
|
this.positionnerHeure(6); // 6 -> lyre
|
|
this.updateDisplay();
|
|
});
|
|
html.find('#calendar-btn-edit').click(ev => {
|
|
ev.preventDefault();
|
|
this.showCalendarEditor();
|
|
});
|
|
html.find('#astrologie-btn-edit').click(ev => {
|
|
ev.preventDefault();
|
|
this.showAstrologieEditor();
|
|
});
|
|
|
|
html.find('#calendar--move-handle').mousedown(ev => {
|
|
ev.preventDefault();
|
|
ev = ev || window.event;
|
|
let isRightMB = false;
|
|
if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
|
|
isRightMB = ev.which == 3;
|
|
} else if ("button" in ev) { // IE, Opera
|
|
isRightMB = ev.button == 2;
|
|
}
|
|
|
|
if (!isRightMB) {
|
|
dragElement(document.getElementById("calendar-time-container"));
|
|
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
|
|
|
function dragElement(elmnt) {
|
|
elmnt.onmousedown = dragMouseDown;
|
|
function dragMouseDown(e) {
|
|
e = e || window.event;
|
|
e.preventDefault();
|
|
pos3 = e.clientX;
|
|
pos4 = e.clientY;
|
|
|
|
document.onmouseup = closeDragElement;
|
|
document.onmousemove = elementDrag;
|
|
}
|
|
|
|
function elementDrag(e) {
|
|
e = e || window.event;
|
|
e.preventDefault();
|
|
// calculate the new cursor position:
|
|
pos1 = pos3 - e.clientX;
|
|
pos2 = pos4 - e.clientY;
|
|
pos3 = e.clientX;
|
|
pos4 = e.clientY;
|
|
// set the element's new position:
|
|
elmnt.style.bottom = null
|
|
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
|
|
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
|
|
elmnt.style.position = 'fixed';
|
|
elmnt.style.zIndex = 100;
|
|
}
|
|
|
|
function closeDragElement() {
|
|
// stop moving when mouse button is released:
|
|
elmnt.onmousedown = null;
|
|
document.onmouseup = null;
|
|
document.onmousemove = null;
|
|
let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth-200 : (elmnt.offsetLeft - pos1);
|
|
let yPos = (elmnt.offsetTop - pos2) > window.innerHeight-20 ? window.innerHeight-100 : (elmnt.offsetTop - pos2)
|
|
xPos = xPos < 0 ? 0 : xPos;
|
|
yPos = yPos < 0 ? 0 : yPos;
|
|
if(xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)){
|
|
elmnt.style.top = (yPos) + "px";
|
|
elmnt.style.left = (xPos) + "px";
|
|
}
|
|
game.system.rdd.calendrier.calendrierPos.top = yPos;
|
|
game.system.rdd.calendrier.calendrierPos.left = xPos;
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos) );
|
|
}
|
|
}
|
|
} else if(isRightMB){
|
|
game.system.rdd.calendrier.calendrierPos.top = 200;
|
|
game.system.rdd.calendrier.calendrierPos.left = 200;
|
|
game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos) );
|
|
this.setPos(game.system.rdd.calendrier.calendrierPos);
|
|
}
|
|
});
|
|
}
|
|
|
|
} |