chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => { try { if (request.action === "getHorseBasicData") { console.log("Getting horse data"); const idEl = document.querySelector('.right:nth-child(2)'); const ageEl = document.querySelector('.right:nth-child(6)'); const genderEl = document.querySelector('img.icon16'); const breedEl = document.querySelector('.right:nth-child(4)'); const horseOwnerEl = document.querySelector('.right:nth-child(14)'); const notesEl = document.querySelector('#notesTextbox'); if (!idEl || !ageEl || !genderEl || !breedEl) { console.error("Some required elements for basic horse data not found on the page."); sendResponse({ success: false, message: "Required elements not found." }); return true; } const idString = idEl.innerText.replace('#', ''); const id = BigInt(idString).toString(); const horseData = { id: parseFloat(id), age: parseInt(ageEl.innerText, 10) || 0, name: (document.title.replace(/ - Horse Reality.*$/, '') || "Unknown").trim(), gender: genderEl.alt || "Unknown", breed: breedEl.innerText || "Unknown", link: window.location.href || "", owner: horseOwnerEl.innerText.replaceAll(/\n.*/g, '') || "Unknown", lastDrawnDate: new Date(Date.now()).toISOString(), notes: notesEl ? notesEl.value : "" }; updateSingleLoadStateUI("Basic", true, false); console.log("Horse data gathered:", horseData); sendResponse({ success: true, data: horseData }); } else if (request.action === "getHorseCurrentData") { console.log("Getting current horse selected tab data"); const selectedTab = getTabselText(); console.log("Selected tab:", selectedTab); if (selectedTab === "Summary") { const pedigreeLinks = document.querySelectorAll('.pedigree a'); if (!pedigreeLinks) { console.warn("No pedigree links found for Summary tab."); sendResponse({ success: false, message: "No pedigree links found." }); return true; } const horseSummaryData = Array.from(pedigreeLinks).map(link => link.href); let horseSummary; console.log("Related horses:", horseSummaryData); const conceptionEl = document.querySelector('.horse_blockimg+ .horse_blocktext p') if (conceptionEl) { conception = conceptionEl.innerText.split(' by')[0].split(' from')[0].replace('Due on', '').replace('Due ', '').trim(); const fatherEl = document.querySelector('.horse_blockimg+ .horse_blocktext p a'); const fatherName = fatherEl.innerText; const fatherLink = fatherEl.href; const ultrasoundGenderEl = document.querySelector('.horse_blocks+ .horse_blocks .horse_blocktitle+ .horse_blocktext p'); let ultrasoundGender; if (ultrasoundGenderEl) { ultrasoundGender = document.querySelector('.horse_blocks+ .horse_blocks .horse_blocktitle+ .horse_blocktext p').innerText.split('\n')[0].trim(); } horseSummary = { RelatedIds: horseSummaryData, Conception: conception, FatherName: fatherName, FatherLink: fatherLink, UltrasoundGender: ultrasoundGender }; } else { horseSummary = { RelatedIds: horseSummaryData }; } //const ultraSonicEl = document.querySelector('.right:nth-child(10)'); try { sendResponse({ success: true, data: "Processing..." }); const response = await setHorseSummaryAPIAsync(request.data.id, horseSummary); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } const jsonData = await response.json(); console.log("API Response:", jsonData); sendResponse({ success: true, data: jsonData }); } catch (error) { console.error("Error in Summary tab:", error); sendResponse({ success: false, message: error.message }); } updateSingleLoadStateUI("Summary", true, false); } else if (selectedTab === "Training") { const trainingEl8 = document.querySelector('.top:nth-child(8)'); const trainingEl6 = document.querySelector('.top:nth-child(6)'); let training; // Überprüfen, ob `trainingEl8` existiert und nicht "Next level" enthält if (trainingEl8 && trainingEl8.innerText !== "Next level") { training = trainingEl8.innerText; } else if (trainingEl6) { // Fallback zu `trainingEl6`, wenn `trainingEl8` "Next level" ist oder nicht existiert training = trainingEl6.innerText; } else { // Standardwert, wenn keiner der beiden existiert oder gültig ist training = "Unknown"; } console.log(training); try { sendResponse({ success: true, data: "Processing..." }); const response = await setHorseTrainingAPIAsync(request.data.id, training); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } const jsonData = await response.json(); console.log("API Response:", jsonData); sendResponse({ success: true, data: jsonData }); } catch (error) { console.error("Error in Training tab:", error); sendResponse({ success: false, message: error.message }); } updateSingleLoadStateUI("Training", true); } else if (selectedTab === "Achievements") { const geneticStatsEls = document.querySelectorAll('.genetic_stats'); if (!geneticStatsEls || geneticStatsEls.length === 0) { console.error("No genetic_stats elements found for Achievements."); sendResponse({ success: false, message: "No genetic_stats found for Achievements." }); return true; } const competitionResults = Array.from(document.querySelectorAll('.row_460 .col_120+ .col_70')) .map(x => parseFloat(x.innerText.trim())) .sort((a, b) => a - b) .filter(x => !isNaN(x)) .length > 0 ? Array.from(document.querySelectorAll('.row_460 .col_120+ .col_70')) .map(x => parseFloat(x.innerText.trim())) .sort((a, b) => a - b) .filter(x => !isNaN(x)) : [document.querySelector('.even > p') ? document.querySelector('.even > p').innerText : '']; const showResults = Array.from(document.querySelectorAll('.row_460 .col_120 + .col_90')) .map(x => parseFloat(x.innerText.trim())) .sort((a, b) => a - b) .filter(x => !isNaN(x)) .length > 0 ? Array.from(document.querySelectorAll('.row_460 .col_120 + .col_90')) .map(x => parseFloat(x.innerText.trim())) .sort((a, b) => a - b) .filter(x => !isNaN(x)) : [document.querySelector('.even > p') ? document.querySelector('.even > p').innerText : '']; const conformation = Object.fromEntries( Array.from(document.querySelectorAll('.genetic_table_row')).flatMap(row => { const keys = Array.from(row.querySelectorAll('.genetic_potential')).map(key => key.innerText.trim()); // Alle Schlüssel holen const values = Array.from(row.querySelectorAll('.genetic_stats')) .map(value => value.innerText.trim()) .filter(value => /poor|below average|average|good|very good/i.test(value)); // Nur relevante Werte behalten return keys.map((key, index) => [key, values[index]]).filter(pair => pair[1]); // Paare mit gültigen Werten }) ); const conformationMapping = { "Good": "G", "Very good": "VG", "Average": "A", "Below average": "BA", "Poor": "P" }; // Alle Werte aus dem bestehenden `conformation`-Objekt durchlaufen let shortConformation = ""; const counts = Object.values(conformation) .filter(value => conformationMapping[value]) // Nur Werte berücksichtigen, die in der Mapping-Tabelle existieren .reduce((counts, value) => { counts[value] = (counts[value] || 0) + 1; // Zähle die Vorkommen jedes Werts return counts; }, {}); // Gehe durch die gezählten Werte und erstelle die Kurzform Object.entries(counts).forEach(([value, count]) => { shortConformation += `${count}${conformationMapping[value]} `; }); // Entferne Leerzeichen am Ende shortConformation = shortConformation.trim(); console.log(shortConformation); try { const achievementTab = { ShowResults: cleanShowResults(showResults), Conformation: conformation, ShortConformation: shortConformation, MaxShowResult: cleanResult(showResults[showResults.length - 1]), MinShowResult: cleanResult(showResults[0]), MaxCompetitionResult: cleanResult(competitionResults[competitionResults.length - 1]), MinCompetitionResult: cleanResult(competitionResults[0]) }; sendResponse({ success: true, data: "Processing..." }); const response = await setHorseAchievementsAPIAsync(request.data.id, achievementTab); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } const jsonData = await response.json(); console.log("API Response:", jsonData); sendResponse({ success: true, data: jsonData }); } catch (error) { console.error("Error in Achievements tab:", error); sendResponse({ success: false, message: error.message }); } updateSingleLoadStateUI("Achievements", true, true); } else if (selectedTab === "Genetics") { try { const gpDiv = Array.from(document.querySelectorAll('.top div')).find(el => el.innerText.includes('GP')); if (!gpDiv) { console.error("No GP element found."); sendResponse({ success: false, message: "No GP element found." }); return true; } const totalGeneticPotentialStr = gpDiv.innerText.replace("GP total: ", "").trim(); const totalGeneticPotential = parseInt(totalGeneticPotentialStr, 10) || 0; const geneticElems = Array.from(document.querySelectorAll('.genetic_name , .genetic_result')); if (geneticElems.length === 0) { console.error("No genetic elements found."); sendResponse({ success: false, message: "No genetic elements found." }); return true; } const geneticDictionary = Object.fromEntries( geneticElems.map(x => x.innerText) .reduce((acc, cur, i, arr) => (i % 2 === 0 ? acc.push([cur, arr[i + 1]]) : null, acc), []) ); // Werte aus Checkboxen sammeln und hinzufügen const checkboxGenetics = getCheckboxGenetics(); const additionalColorTextboxValue = document.querySelector('#optionalColorTextbox').value; if (additionalColorTextboxValue.trim() !== "") { checkboxGenetics["Custom"] = additionalColorTextboxValue; } Object.assign(geneticDictionary, checkboxGenetics); const geneticsStats = Array.from(document.querySelectorAll('.genetic_stats')); if (geneticsStats.length < 10) { console.error("Not enough genetic stats found."); sendResponse({ success: false, message: "Not enough genetic stats found for genetics calculation." }); return true; } const geneticPotentialList = geneticsStats .map(x => x.innerText.trim()) .filter(value => !isNaN(value) && value !== "") .map(value => parseFloat(value)); const GeneticPotential = { GP: totalGeneticPotential, GeneticPotential: { "Acceleration": geneticPotentialList[0], "Agility": geneticPotentialList[1], "Balance": geneticPotentialList[2], "Bascule": geneticPotentialList[3], "Pulling power": geneticPotentialList[4], "Speed": geneticPotentialList[5], "Sprint": geneticPotentialList[6], "Stamina": geneticPotentialList[7], "Strength": geneticPotentialList[8], "Surefootedness": geneticPotentialList[9] }, Disciplines: { "Dressage": geneticPotentialList[1] + geneticPotentialList[2] + geneticPotentialList[8], "Driving": geneticPotentialList[1] + geneticPotentialList[4] + geneticPotentialList[5] + geneticPotentialList[7] + geneticPotentialList[8], "Endurance": geneticPotentialList[5] + geneticPotentialList[7] + geneticPotentialList[8] + geneticPotentialList[9], "Eventing": geneticPotentialList[2] + geneticPotentialList[3] + geneticPotentialList[5] + geneticPotentialList[8] + geneticPotentialList[9], "Flat Racing": geneticPotentialList[5] + geneticPotentialList[0] + geneticPotentialList[7] + geneticPotentialList[6], "Show Jumping": geneticPotentialList[0] + geneticPotentialList[1] + geneticPotentialList[3] + geneticPotentialList[6] + geneticPotentialList[8], "Western Reining": geneticPotentialList[0] + geneticPotentialList[1] + geneticPotentialList[2] + geneticPotentialList[9] }, Colors: geneticDictionary }; console.log("Genetic Potential:", GeneticPotential); sendResponse({ success: true, data: "Processing..." }); const response = await setHorseGeneticsAPIAsync(request.data.id, GeneticPotential); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } const jsonData = await response.json(); console.log("API Response:", jsonData); sendResponse({ success: true, data: jsonData }); } catch (error) { console.error("Error while processing Genetics tab:", error); sendResponse({ success: false, message: error.message }); } updateSingleLoadStateUI("Genetics", true, false); } else if (selectedTab === "Health") { const healthEl = document.querySelector("#tab_health2 p"); if (!healthEl) { console.error("Health element not found."); sendResponse({ success: false, message: "Health element not found." }); return true; } const matches = [...healthEl.innerText.matchAll(/:\s*(\w+)/g)]; const health = Object.fromEntries(document.querySelector("#tab_health2 p").innerText.split('\n').map(l=>l.trim()).filter(l=>l&&l.includes(':')).map(l=>l.split(':').map(x=>x.trim()))); console.log("Health data:", health); try { sendResponse({ success: true, data: "Processing..." }); const response = await setHorseHealthAPIAsync(request.data.id, health); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } const jsonData = await response.json(); console.log("API Response:", jsonData); sendResponse({ success: true, data: jsonData }); } catch (error) { console.error("Error in Health tab:", error); sendResponse({ success: false, message: error.message }); } updateSingleLoadStateUI("Health", true, false); } else { console.warn("Unknown or no tab selected."); sendResponse({ success: false, message: "Unknown or no tab selected." }); } } else if (request.action === "deleteHorse") { const idEl = document.querySelector('.right:nth-child(2)'); const idString = idEl.innerText.replace('#', ''); const id = BigInt(idString).toString(); sendResponse({ success: true, data: "Processing..." }); console.log("Deleting horse with ID:", id); const response = await deleteHorseAPIAsync(id); if (!response.ok) { console.error("API returned an error:", response.statusText); sendResponse({ success: false, message: "API error: " + response.statusText }); return true; } updateLoadStateUI(id); } else { console.error("Unsupported action:", request.action); sendResponse({ success: false, message: "Unsupported action." }); } } catch (error) { console.error("Unexpected error occurred:", error); sendResponse({ success: false, message: error.message }); } return true; // Wichtig, um asynchrone Antworten zu ermöglichen }); function getTabselText() { return document.querySelector('div.tabsel')?.textContent?.trim() || "Unknown"; } function cleanResult(value) { // Check if the value is not a number or cannot be converted to a number if (isNaN(value) || value === null || value === undefined || value === "") { return -1; } return parseFloat(value); // Convert to a number if it is valid } function cleanShowResults(results) { // Überprüfen, ob das Array gültig ist if (!Array.isArray(results)) { console.error("Invalid ShowResults data: not an array."); return []; } // Bereinigen der Ergebnisse return []; } function getCheckboxGenetics() { return { "RAB": getCheckboxValue('#checkboxRAB1', '#checkboxRAB2', "RAB"), "Seal": getCheckboxValue('#checkboxSeal1', '#checkboxSeal2', "AT"), "Flaxen": getCheckboxValue('#checkboxFlaxen1', '#checkboxFlaxen2', "f"), "Sooty": getCheckboxValue('#checkboxSooty1', '#checkboxSooty2', "Sty"), "Pangare": getCheckboxValue('#checkboxPangare1', '#checkboxPangare2', "P"), "Sabino": getCheckboxValue('#checkboxSabino1', '#checkboxSabino2', "Ab") }; } // Funktion zur Bestimmung des Wertes basierend auf beiden Checkboxen function getCheckboxValue(checkbox1Selector, checkbox2Selector, marker) { const checkbox1 = document.querySelector(checkbox1Selector); const checkbox2 = document.querySelector(checkbox2Selector); const isCheckbox1Checked = checkbox1?.checked || false; const isCheckbox2Checked = checkbox2?.checked || false; if (isCheckbox1Checked && isCheckbox2Checked) { return `${marker}/${marker}`; } else if (isCheckbox1Checked) { return `${marker}/n`; } else if (isCheckbox2Checked) { return `n/${marker}`; } else { return `n/n`; } }