#include "Includes.h"
#include "tinyfiledialogs.h"
#include <cstddef>
#include <cstdio>
#include <raylib.h>
func::func(){}
func::~func(){}
bool func::isAlarmTime(const char* alarmTime) {
time_t now = time(0);
tm *ltm = localtime(&now);
char currentTime[6];
sprintf(currentTime, "%02d:%02d", ltm->tm_hour, ltm->tm_min);
return strncmp(alarmTime, currentTime, 5) == 0;
}
void func::sizeInitWindow(Vector2 XY, const char *title, int set) {
if (set == 1) {
InitWindow(XY.x, XY.y, title);
}else{
InitWindow(GetMonitorWidth(1), GetMonitorHeight(1), title);
}
}
std::vector<Music> func::LoadMusicFiles(const std::vector<const char*>& fileNames) {
for (const auto& fileName : fileNames) {
Music music = LoadMusicStream(fileName);
if (music.stream.buffer != nullptr) { // Ensure the music is loaded successfully
v.musicFiles.push_back(music);
} else {
std::cerr << "Failed to load music file: " << fileName << std::endl;
}
}
return v.musicFiles;
}
void func::drawRect(Rectangle rec, float roundness, int segments, float lineThick, Color color, int rectType){
if(rectType == 0){
DrawRectangleRec(rec, color);
}else if (rectType == 1){
DrawRectangleLinesEx(rec, lineThick, color);
}else if (rectType == 2){
DrawRectangleRounded(rec, roundness, segments, color);
}else if (rectType == 3){
DrawRectangleRoundedLines(rec, roundness, segments, lineThick, color);
}
}
Vector2 func::mousePoint(){
Vector2 mousePnt = { 0.0f, 0.0f };
mousePnt = GetMousePosition();
return mousePnt;
}
bool func::textRect(const char *text, float x, float y, Font fontt, Color tColor, Color rColor, int fontSize, int rectType){
float textSizeX = MeasureTextEx(fontt, text, fontSize, 1.0f).x;
float textSizeY = MeasureTextEx(fontt, text, fontSize, 1.0f).y;
Vector2 centerText = {textSizeX / 2.0f, textSizeY / 2.0f};
Rectangle selecText = { x - centerText.x, y - centerText.y, textSizeX + 2, textSizeY};
DrawTextPro(GetFontDefault(), text, (Vector2){x, y}, (Vector2){textSizeX / 2.0f, textSizeY / 2.0f}, 0.0f, (float)fontSize, 1, tColor);
if(CheckCollisionPointRec(mousePoint(), selecText)){
drawRect(selecText, 1, 1, 1, rColor, rectType);
DrawTextPro(GetFontDefault(), text, (Vector2){x, y}, (Vector2){textSizeX / 2.0f, textSizeY / 2.0f}, 0.0f, (float)fontSize, 1, tColor);
return true;
}else{
drawRect(selecText, 1, 1, 1, BLANK, rectType);
DrawTextPro(GetFontDefault(), text, (Vector2){x, y}, (Vector2){textSizeX / 2.0f, textSizeY / 2.0f}, 0.0f, (float)fontSize, 1, tColor);
return false;
}
}
NEWENTITY Entity = NEWENTITY::NONEADDED;
MAIN E_Main;
func::rectTabs botTabs;
func::rectTabs sidTabs;
func::rectTabs keyPad;
void func::newEntity(){
float fontSize;
const char *vertText[] = {"M", "u", "s", "i", "c", "A", "l", "a", "r", "m"};
switch (Entity) {
case NEWENTITY::NONEADDED:
textRect("+", v.centreScreen().x, v.centreScreen().y, GetFontDefault(), BLACK, GRAY, 50, 0);
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && textRect("+", v.centreScreen().x, v.centreScreen().y, GetFontDefault(), BLACK, GRAY, 50, 0)){
Entity = NEWENTITY::SELECTION;
break;
}
break;
case NEWENTITY::SELECTION:
textRect("AddMusic", v.centreScreen().x, v.centreScreen().y - 75, GetFontDefault(), BLACK, GRAY, 50, 0);
textRect("AddAlarm", v.centreScreen().x, v.centreScreen().y, GetFontDefault(), BLACK, GRAY, 50, 0);
textRect("AddTimeZone", v.centreScreen().x, v.centreScreen().y + 75, GetFontDefault(), BLACK, GRAY, 50, 0);
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && textRect("AddMusic", v.centreScreen().x, v.centreScreen().y - 75, GetFontDefault(), BLACK, GRAY, 50, 0)){
Entity = NEWENTITY::ADD_MUSIC;
break;
}else if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && textRect("AddAlarm", v.centreScreen().x, v.centreScreen().y, GetFontDefault(), BLACK, GRAY, 50, 0)){
Entity = NEWENTITY::ADD_ALARM;
break;
}else if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && textRect("AddTimeZone", v.centreScreen().x, v.centreScreen().y + 75, GetFontDefault(), BLACK, GRAY, 50, 0)){
Entity = NEWENTITY::ADD_CLOCKTZ;
break;
}
break;
case NEWENTITY::ADD_MUSIC:
addMusic();
break;
case NEWENTITY::ADD_ALARM:
{
v.rectPad = keyPad.setRowCol(4, 3).setRectPos(GetScreenWidth() / 2, GetScreenHeight() / 3).setTabSize(GetScreenWidth() / 5, 50.0f)
.setOverlap(0.25f)
.setMainColor(GRAY).setOLColor(BLACK).setTabText("1234567890", 3).DrawTabs(1);
}
break;
case NEWENTITY::ADD_CLOCKTZ:
break;
case NEWENTITY::MAIN:
{
textRect("+", v.GetWindowSize().x - 40, GetScreenHeight() / 30.0f, GetFontDefault(), BLACK, GRAY, 37, 0);
v.bottomTabs = botTabs.setRowCol(1, 4).setRectPos(GetScreenWidth() / 2, GetScreenHeight() - 25.0f).setTabSize(GetScreenWidth() / 5.25f, 50.0f)
.setOverlap(0.25f)
.setMainColor(GRAY).setOLColor(BLACK).setTabText("Music", 1).DrawTabs(1);
v.sideTabs = sidTabs.setRowCol(2, 1).setRectPos(25.0f, GetScreenHeight() / 2).setTabSize(50.0f, GetScreenHeight() / 2.25f).setOverlap(0.25f).setMainColor(GRAY).setOLColor(BLACK).setTabText("Music Alarm", 2).DrawTabs(1);
v.textureMusic = {"/res/ic-twotone-timer.svg"};
v.textureAlarm = {"/res/pixelart--clock.svg"};
if (v.areTexturesLoaded) {
for (size_t i = 0; i < v.spriteG.size(); ++i) {
DrawTexture(v.spriteG[i], 100 + i * 110, 100, WHITE);
}
}
switch (E_Main){
case MAIN::MUSIC:
if (v.areTexturesLoaded) {
for (size_t i = 0; i < v.spriteG.size(); i++) {
DrawTexture(v.spriteG[i], 100 + i * 110, 100, WHITE);
}
}
break;
case MAIN::ALARM:
break;
default:
DrawText("default", 100, 100, 20, BLACK);
break;
}
}
break;
default:
break;
}
}
void func::addMusic(){
if(Entity == NEWENTITY::ADD_MUSIC){
const char* filterPatterns[2] = { "*.wav", "*.mp3"};
//tinyfd_openFileDialog(const char *aTitle, const char *aDefaultPathAndFile, int aNumOfFilterPatterns, const char *const *aFilterPatterns, const char *aSingleFilterDescription, int aAllowMultipleSelects)
const char* musicFile = tinyfd_openFileDialog(
"Select Music File",
"",
2,
filterPatterns,
NULL,
1
);
if (musicFile != NULL) {
Music music = LoadMusicStream(musicFile);
v.musicFiles.push_back(music);
Entity = NEWENTITY::MAIN;
}else{
Entity = NEWENTITY::SELECTION;
}
}else{
Entity = NEWENTITY::SELECTION;
}
}
void func::parseTime(const char* timeString, int& hour, int& minute) {
hour = std::atoi(std::string(timeString, timeString + 2).c_str()); // Extracts the first 2 characters as the hour
minute = std::atoi(std::string(timeString + 3, timeString + 5).c_str()); // Extracts the last 2 characters as the minute
}
void func::addAlarm(const char* timeString) {
int hour, minute;
parseTime(timeString, hour, minute);
}
template<typename T>
T doSomething(T arg1, T arg2) {
return arg1 && arg2;
}
// void doAnotherThing() {
// int a = 10;
// int z = doSomething<int>(a);
// std::string b = doSomething<std::string>("Hello World");
// }
func::rectTabs::rectTabs() : overlap(0.25f),
roundness(0.75f), smoothness(100), lineThick(2.25f){
//tabSize = {50.0f, 50.0f};
}
Rectangle func::rectTabs::DrawTabs(int sel) {
Rectangle tabRec;
int textIndex = 0;
std::vector<Rectangle> tabRects;
P_passRect = {RectPos().x, RectPos().y, TabSize().x, TabSize().y};
for (X = 0; X < C; X++) {
for (Y = 0; Y < R; Y++) {
float tabWidth = P_passRect.width + Overlap();
float tabHeight = P_passRect.height + Overlap();
if (sel == 0) {
tabRec = {P_passRect.x + X * (tabWidth - Overlap()), P_passRect.y + Y * (tabHeight - Overlap()), tabWidth, tabHeight};
} else if (sel == 1) {
float tabWidth = GetCentre().width + Overlap();
float tabHeight = GetCentre().height + Overlap();
tabRec = {GetCentre().x + X * (tabWidth - Overlap()), GetCentre().y + Y * (tabHeight - Overlap()), tabWidth, tabHeight};
} else {
throw std::out_of_range("Index must be 0 or 1");
}
DrawRectangleRoundedLines(tabRec, Roundness(), Smoothness(), LineThick(), OutlineColor());
DrawRectangleRounded(tabRec, Roundness(), Smoothness(), MainColor());
bool isMouseOverTab = false;
isMouseOverTab = (F.mousePoint().x > tabRec.x + 12 && F.mousePoint().x < (tabRec.x + tabRec.width) &&
F.mousePoint().y > tabRec.y + 12 && F.mousePoint().y < (tabRec.y + tabRec.height));
if (isMouseOverTab && isSelected == false) {
// Highlight the tab
//DrawRectangleRoundedLinesEx(tabRec, Roundness(), Smoothness(), LineThick(), LIGHTGRAY);
DrawRectangleRoundedLines(tabRec, Roundness(), Smoothness(), LineThick(), LIGHTGRAY);
char buf[20];
sprintf(buf, "%d", (int)tabRec.y * (Y + 1));
DrawText(buf, tabRec.x + 10, tabRec.y + 10, 20, GREEN);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
isSelected = true;
}
}
if (isMouseOverTab && isSelected == true) {
//DrawRectangleRoundedLinesEx(tabRec, Roundness(), Smoothness(), LineThick(), GOLD);
DrawRectangleRoundedLines(tabRec, Roundness(), Smoothness(), LineThick(), GOLD);
}
tabRects.push_back(tabRec);
}
}
if (textMode != NO && textIndex < v.charInsert.size()) {
float fontSize = 25.0f;
float rotation = 0.0f;
float textSizeX = MeasureTextEx(GetFontDefault(), v.charInsert[textIndex], fontSize, 1.0f).x;
float textSizeY = MeasureTextEx(GetFontDefault(), v.charInsert[textIndex], fontSize, 1.0f).y;
Vector2 position;
if (textMode == WORDx && textIndex < v.charInsert.size()) {
// Determine the total length of the combined word
int totalLength = 0;
Vector2 origin;
for (const char* letter : v.charInsert) {
totalLength += strlen(letter);
}
// Allocate a char array to store the combined word
char* combinedWord = new char[totalLength + 1]; // +1 for the null terminator
combinedWord[0] = '\0'; // Start with an empty string
// Concatenate each letter into combinedWord
for (const char* letter : v.charInsert) {
strcat(combinedWord, letter);
}
// Measure the size of the combined word
float textSizeXn = MeasureTextEx(GetFontDefault(), combinedWord, fontSize, 1.0f).x;
float textSizeYn = MeasureTextEx(GetFontDefault(), combinedWord, fontSize, 1.0f).y;
origin = {textSizeXn / 2.0f, textSizeYn / 2.0f};
position = {
GetCentre().x + (P_passRect.width) / 2,
GetCentre().y + (P_passRect.height) / 2
};
// Draw the combined word once in the center of the current tab
DrawTextPro(GetFontDefault(), combinedWord, position, origin, rotation, fontSize, 1.0f, BLACK);
// Move to the next tab only after drawing once
//textIndex++;
// Clean up dynamically allocated memory
delete[] combinedWord;
}else if (textMode == WORDy && textIndex < v.charInsert.size()) {
float lineHeight = fontSize * 1.2f; // Adjust line spacing as needed
Vector2 origin;
// Calculate the vertical starting position for this word to be centered within the current tab
float totalTextHeight = 0;
int wordLength = 0;
// Calculate the total height of the word by iterating over letters until a space or end
int tempIndex = textIndex;
while (tempIndex < v.charInsert.size() && *v.charInsert[tempIndex] != ' ') {
totalTextHeight += lineHeight;
wordLength++;
tempIndex++;
}
// Calculate the initial centered position for the word in the current tab
Vector2 position = {
GetCentre().x + (P_passRect.width) / 2,
tabRec.y + (tabRec.height - totalTextHeight) / 2 // Center the word vertically
};
// Draw each letter in the word within the current tab
for (int i = 0; i < wordLength && textIndex < v.charInsert.size(); i++) {
float textSizeX = MeasureTextEx(GetFontDefault(), v.charInsert[textIndex], fontSize, 1.0f).x;
origin = {textSizeX / 2.0f, 0}; // Center each letter horizontally
// Draw the current letter
DrawTextPro(GetFontDefault(), v.charInsert[textIndex], position, origin, rotation, fontSize, 1.0f, BLACK);
// Move position down for the next letter in the word
position.y += lineHeight;
textIndex++;
}
// Move past the space character, if any, to start the next word on the next tab
if (textIndex < v.charInsert.size() && *v.charInsert[textIndex] == ' ') {
textIndex++;
}
}else if (textMode == LETTERx && textIndex < v.charInsert.size()) {
float fontSize = 25.0f;
float rotation = 0.0f;
// Iterate over stored rectangles and draw characters
for (const auto& rect : tabRects) {
if (textIndex >= v.charInsert.size()) break;
// Measure the size of the current character
float textSizeX = MeasureTextEx(GetFontDefault(), v.charInsert[textIndex], fontSize, 1.0f).x;
float textSizeY = MeasureTextEx(GetFontDefault(), v.charInsert[textIndex], fontSize, 1.0f).y;
// Center the character within the current tab
Vector2 position = {
rect.x + (rect.width - textSizeX) / 2.0f,
rect.y + (rect.height - textSizeY) / 2.0f
};
// Draw the character
DrawTextPro(GetFontDefault(), v.charInsert[textIndex], position, {0.0f, 0.0f}, rotation, fontSize, 1.0f, BLACK);
// Move to the next character
textIndex++;
}
} else if (textMode == LETTERy && textIndex < v.charInsert.size()) {
float fontSize = 25.0f;
float rotation = 0.0f;
Vector2 origin;
// Get text size for centering each character within the tab
origin = {textSizeX / 2.0f, textSizeY / 2.0f};
// Calculate position based on the current grid index (X, Y)
position = {
tabRec.x + (tabRec.width - textSizeX) / 2,
tabRec.y + (tabRec.height - textSizeY) / 2
};
// Draw the current letter centered within its tab cell
DrawTextPro(GetFontDefault(), v.charInsert[textIndex], position, origin, rotation, fontSize, 1.0f, BLACK);
// Move to the next letter in v.charInsert
textIndex++;
}
}
return tabRec;
}
int func::rectTabs::RowCol(int index) {
int XXorYY[2] = {R, C}; // 0 = R (rows), 1 = C (columns)
if (index < 0 || index > 1) {
throw std::out_of_range("Index must be 0 or 1");
}
return XXorYY[index];
}
func::rectTabs func::rectTabs::setRowCol(int row, int col){
R = row;
C = col;
return *this;
}
Rectangle func::rectTabs::GetCentre(){
float totalWidth = P_passRect.width; // Total width accounting for overlaps
float totalHeight = P_passRect.height; // Total height accounting for overlaps
float centerX = rectPos.x - totalWidth / 2.0f * C; // Center x based on total width
float centerY = rectPos.y - totalHeight / 2.0f * R; // Center y based on total height
return {centerX, centerY, totalWidth, totalHeight};
}
Vector2 func::rectTabs::RectPos(){
return rectPos;
}
func::rectTabs func::rectTabs::setRectPos(float x, float y) {
rectPos = {x, y};
return *this;
}
Vector2 func::rectTabs::TabSize() {
return tabSize;
}
func::rectTabs func::rectTabs::setTabSize(float w, float h) {
tabSize = {w, h};
return *this;
}
float func::rectTabs::Overlap() {
return overlap;
}
func::rectTabs func::rectTabs::setOverlap(float value) {
overlap = value;
return *this;
}
float func::rectTabs::Roundness() {
return roundness;
}
func::rectTabs func::rectTabs::setRoundness(float value) {
roundness = value;
return *this;
}
int func::rectTabs::Smoothness() {
return smoothness;
}
func::rectTabs func::rectTabs::setSmoothness(int value) {
smoothness = value;
return *this;
}
float func::rectTabs::LineThick() {
return lineThick;
}
func::rectTabs func::rectTabs::setLineThick(float value) {
lineThick = value;
return *this;
}
bool func::rectTabs::Clicked(){
return isSelected;
}
func::rectTabs func::rectTabs::isClicked(bool value) {
isSelected = value;
return *this;
}
Color func::rectTabs::MainColor(){
return m_color;
}
func::rectTabs func::rectTabs::setMainColor(Color value) {
m_color = value;
return *this;
}
Color func::rectTabs::OutlineColor(){
return OL_Color;
}
func::rectTabs func::rectTabs::setOLColor(Color value) {
OL_Color = value;
return *this;
}
int func::rectTabs::getTextMode(){
return textMode;
}
func::rectTabs func::rectTabs::setTabText(const char* inputText, int mode, int startIndex) {
v.charInsert.clear();
textMode = mode;
for (const char* letter = inputText; *letter != '\0'; ++letter) {
char* singleLetter = new char[2];
singleLetter[0] = *letter;
singleLetter[1] = '\0';
v.charInsert.push_back(singleLetter);
}
//textIndex++; // Move to the next text item in charInsert
return *this; // Return *this to allow method chaining
}
// func::rectTabs func::rectTabs::setTabText(const char* inputText, int mode, int startIndex) {
// v.charInsert.clear();
// textMode = mode;
// if (mode == WORD) {
// const char* wordStart = inputText;
// while (*wordStart != '\0') {
// const char* wordEnd = wordStart;
// while (*wordEnd != '\0' && *wordEnd != ' ') {
// wordEnd++;
// }
// // Include the space if the word ends with it
// int length = (wordEnd - wordStart) + (*wordEnd == ' ' ? 1 : 0);
// char* word = new char[length + 1];
// strncpy(word, wordStart, length);
// word[length] = '\0';
// v.charInsert.push_back(word);
// wordStart = (*wordEnd == '\0') ? wordEnd : wordEnd + 1; // Move to the next word
// }
// } else if (mode == LETTER) {
// while (*inputText != '\0') {
// char* letter = new char[2];
// letter[0] = *inputText;
// letter[1] = '\0';
// v.charInsert.push_back(letter);
// inputText++;
// }
// }
// // Adjust the vector to start at the specified index
// if (startIndex < v.charInsert.size()) {
// v.charInsert.erase(v.charInsert.begin(), v.charInsert.begin() + startIndex);
// }
// return *this; // Return *this to allow method chaining
// }
// func::rectTabs func::rectTabs::setTabText(const char* inputText, int mode, int startIndex) {
// v.charInsert.clear();
// textMode = mode;
// if (mode == WORD) {
// const char* wordStart = inputText;
// while (*wordStart != '\0') {
// const char* wordEnd = wordStart;
// while (*wordEnd != '\0' && *wordEnd != ' ') {
// wordEnd++;
// }
// // Include space at the end of the word if there's one
// int length = (wordEnd - wordStart) + (*wordEnd == ' ' ? 1 : 0);
// char* word = new char[length + 1];
// strncpy(word, wordStart, length);
// word[length] = '\0';
// v.charInsert.push_back(word);
// wordStart = wordEnd + 1; // Move to the start of the next word
// }
// } else if (mode == LETTER) {
// while (*inputText != '\0') {
// char* letter = new char[2];
// letter[0] = *inputText;
// letter[1] = '\0';
// v.charInsert.push_back(letter);
// inputText++;
// }
// }
// // Adjust vector to start at specified index
// if (startIndex < v.charInsert.size()) {
// v.charInsert.erase(v.charInsert.begin(), v.charInsert.begin() + startIndex);
// }
// return *this; // Return *this to allow method chaining
// }
// func::rectTabs func::rectTabs::setTabText(const char* inputText, int mode, int startIndex){
// v.charInsert.clear();
// //#define NO 0
// //#define WORD 1
// //#define LETTER 2
// textMode = mode;
// if (mode == WORD) {
// const char* wordStart = inputText;
// while (*wordStart != '\0') {
// const char* wordEnd = wordStart;
// while (*wordEnd != ' ' && *wordEnd != '\0') {
// wordEnd++;
// }
// if (wordEnd > wordStart) {
// char* word = new char[wordEnd - wordStart + 1];
// strncpy(word, wordStart, wordEnd - wordStart);
// word[wordEnd - wordStart] = '\0';
// v.charInsert.push_back(word);
// }
// wordStart = (*wordEnd == '\0') ? wordEnd : wordEnd + 1;
// }
// } else if (mode == LETTER) {
// while (*inputText != '\0') {
// if (*inputText != ' ') {
// char* letter = new char[2];
// letter[0] = *inputText;
// letter[1] = '\0';
// v.charInsert.push_back(letter);
// }
// inputText++;
// }
// }
// // Adjust vector to start at specified index
// if (startIndex < v.charInsert.size()) {
// v.charInsert.erase(v.charInsert.begin(), v.charInsert.begin() + startIndex);
// }
// return *this; // Return *this to allow method chaining
// }
// const char* func::rectTabs::setTabText(const char* inputText, int startIndex) {
// v.charInsert.clear();
// //textMode = mode;
// if (mode == WORD) {
// const char* wordStart = inputText;
// while (*wordStart != '\0') {
// const char* wordEnd = wordStart;
// while (*wordEnd != ' ' && *wordEnd != '\0') {
// wordEnd++;
// }
// if (wordEnd > wordStart) {
// char* word = new char[wordEnd - wordStart + 1];
// strncpy(word, wordStart, wordEnd - wordStart);
// word[wordEnd - wordStart] = '\0';
// v.charInsert.push_back(word);
// }
// wordStart = (*wordEnd == '\0') ? wordEnd : wordEnd + 1;
// }
// } else if (mode == LETTER) {
// while (*inputText != '\0') {
// if (*inputText != ' ') {
// char* letter = new char[2];
// letter[0] = *inputText;
// letter[1] = '\0';
// v.charInsert.push_back(letter);
// }
// inputText++;
// }
// }
// // Adjust vector to start at specified index
// if (startIndex < v.charInsert.size()) {
// v.charInsert.erase(v.charInsert.begin(), v.charInsert.begin() + startIndex);
// }
// return v.charInsert.empty() ? "" : v.charInsert[0];
// //return inputText;
// }
Rectangle func::rectTabs::PassRect(){
return P_passRect;
}
func::rectTabs func::rectTabs::setRect(Rectangle passedRec){
P_passRect = passedRec;
return *this;
}
void func::mainFunctions(){
newEntity();
char buffer[100];
sprintf(buffer, "%d", Entity);
if (IsMouseButtonPressed(0)) {
DrawText(buffer, 150, 150, 20, RED);
}
DrawText(buffer, 10, 10, 20, RED);
}
void func::LoadGlobalTextures(const std::vector<const char*>& fileNames) {
if (!v.areTexturesLoaded) {
for (const char* fileName : fileNames) {
v.spriteG.push_back(LoadTexture(fileName));
}
v.areTexturesLoaded = true;
}
}
void func::UnloadGlobalTextures() {
if (v.areTexturesLoaded) {
for (Texture2D texture : v.spriteG) {
UnloadTexture(texture);
}
v.spriteG.clear();
v.areTexturesLoaded = false;
}
}