1$(document).ready(function () { 2 /* $('#faoHeader').show(); 3 4 var headingHTML = ` 5 <div id="transboundaryListTitle" class="bg-white border-bottom shadow-sm mb-4 py-3"> 6 <h1 class="text-center m-0 text-primary fw-normal fs-4"> 7 Transboundary Breed Summary 8 </h1> 9 </div> 10 `; 11 $('#faoHeader').after(headingHTML); */ 12 13 // Inizializza i Tooltip nativi di Bootstrap 5 14 var tooltipTriggerList = [].slice.call(document.querySelectorAll('[title]')) 15 var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { 16 return new bootstrap.Tooltip(tooltipTriggerEl) 17 }); 18 19 startup(); 20}); 21 22var i18nData = {}; 23var speciesMap = new Map(); 24 25//** WS ** 26//** WS ** 27const ENVIRONMENT_DADIS = "https://dadis-ws.firebaseio.com"; 28const ENVIRONMENT_TABLEAU = "https://dadis-ws-tableau.firebaseio.com"; 29//const BREED_DATA_SHEET_URL = "https://dadis-tools-ws.web.app/breed-data-sheet"; 30//const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-ws.web.app/transboundary-breed-details'; 31const BREED_DATA_SHEET_URL = 'https://dadis-breed-datasheet-ws.firebaseapp.com/'; 32//const BREED_DATA_SHEET_URL = "https://dadis-tools-ws.web.app/breed-data-sheet"; 33const SINGLE_TRANSBOUNDARY_CALLBACK = "https://dadis-transboundary-breed-ws.web.app"; 34//const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-ws.web.app/transboundary-breed-details'; 35/////////////////////////*/ 36 37/*//** TARINING ** 38 const ENVIRONMENT_DADIS = "https://dadis-training.firebaseio.com"; 39 const ENVIRONMENT_TABLEAU = "https://dadis-training-tableau.firebaseio.com"; 40 const BREED_DATA_SHEET_URL = "https://dadis-tools-qa.web.app/breed-data-sheet"; 41 const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-qa.web.app/transboundary-breed-details'; 42/////////////////////////*/ 43 44//** DEV ** 45/* const ENVIRONMENT_DADIS = "https://fao-dadis-dev.firebaseio.com"; 46 const ENVIRONMENT_TABLEAU = "https://dadis-training-tableau.firebaseio.com"; 47 const BREED_DATA_SHEET_URL = "https://dadis-tools-dev.web.app/breed-data-sheet"; 48 const SINGLE_TRANSBOUNDARY_CALLBACK = "https://dadis-transboundary-breed-dev.web.app"; 49/////////////////////////*/ 50 51 52var LANG = 'en'; 53var TARGET_LANG = 'en'; 54var isExternal = false; 55var specieVal = ""; 56var transboundaryVal = ""; 57var countryMap = new Map(); 58 59var getCountryIsoNameMap = function () { 60 return new Promise(function (resolve, reject) { 61 var url = ENVIRONMENT_DADIS + '/Data/countries.json'; 62 $.getJSON(url, function (countries) { 63 if (countries == null || typeof countries === 'undefined') reject('Country Node Not Found!!!'); 64 else { 65 for (let ISO in countries) { 66 countryMap.set(ISO, countries[ISO]['names'][LANG]); 67 } 68 resolve(countryMap); 69 } 70 }); 71 }); 72} 73 74var startup = function () { 75 isExternal = get("external") == "1" ? true : false; 76 specieVal = get("species") == "all" ? "" : get("species"); 77 transboundaryVal = get("transboundary") == "all" ? "" : get("transboundary"); 78 LANG = get("lang") ? get("lang") : 'en'; 79 80 if (LANG != 'en' && LANG != 'es' && LANG != 'fr' && LANG != 'ru' && LANG != 'ch') LANG = 'en'; 81 82 loadBundles(LANG); 83 84 loadI18nLocalData().then((data) => { i18nData = data; }); 85 86 $.when(getCountryIsoNameMap(), getSpeciesNameMap()) 87 .done(function () { getSpecies(); }) 88 .fail(function (error) { console.log(error); }); 89 90 if (isExternal) { 91 $('#breedSearchForm').remove(); 92 $('#faoHeader').show(); 93 getTransboundaryRisk(); 94 } 95} 96 97function get(name) { 98 if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search)) 99 return decodeURIComponent(name[1]); 100} 101 102function loadBundles(lang) { 103 jQuery.i18n.properties({ 104 name: 'message', 105 path: 'assets/locale/messages/', 106 mode: 'both', 107 language: lang, 108 callback: function () { translateLabels(); } 109 }); 110} 111 112var getSpecies = function () { 113 var url = ENVIRONMENT_DADIS + '/Data/Transboundary/species.json'; 114 $.getJSON(url, function (species) { 115 if (species == null || species.lenght == 0) { 116 $('#spinner').hide(); 117 $('#generalError').show(); 118 } else { 119 var specieSelect = $('#specieSelect'); 120 for (var specie in species) { 121 specieSelect.append('<option value="' + specie + '">' + speciesMap.get(specie)[LANG] + '</option>'); 122 specieSelect.select2({ 123 theme: 'bootstrap-5', 124 width: '100%', 125 }); 126 } 127 128 if (!isExternal) { 129 $('#spinner').hide(); 130 $('#profileCard').hide(); 131 $('#transboundaryTableFields').hide(); 132 $('#breedSearchForm').show(); 133 $('#searchBreedMessage').show(); 134 } 135 } 136 }); 137} 138 139var speciesListOrdered = [] 140var getSpeciesNameMap = function () { 141 speciesListOrdered = [] 142 return new Promise(function (resolve, reject) { 143 var url = ENVIRONMENT_DADIS + '/Data/species.json?callback=?'; 144 $.getJSON(url, function (species) { 145 if (species == null || typeof species === 'undefined') reject('Species Node Not Found!!!'); 146 else { 147 for (let speciesItem in species) { 148 speciesMap.set(speciesItem, species[speciesItem]['names']); 149 } 150 resolve(speciesMap); 151 } 152 }); 153 }); 154} 155 156function reorderObjectMapToArray(map, lang) { 157 var newList = []; 158 var keys = Object.keys(map); 159 for (let key in keys) newList.push(map[keys[key]]); 160 newList.sort(function (a, b) { 161 try { return a.names[lang].localeCompare(b.names[lang]); } 162 catch (error) { console.error(error); } 163 }); 164 return newList; 165} 166 167var getTransboundary = function () { 168 $('#profileCard').hide(); 169 $('#transboundaryTableFields').hide(); 170 $('#transboundarySelect').find('option').remove().end().append('<option value="" selected>Choose a transboundary</option>'); 171 172 var selectedTransboundary = $('#specieSelect').val(); 173 if (!selectedTransboundary) return; 174 175 var url = ENVIRONMENT_DADIS + '/Data/Transboundary/species/' + selectedTransboundary + '.json'; 176 $.getJSON(url, function (transboundary) { 177 if (transboundary == null || transboundary.lenght == 0) { 178 $('#spinner').hide(); 179 $('#generalError').show(); 180 } else { 181 var transboundarySelect = $('#transboundarySelect'); 182 for (var transb in transboundary) { 183 transboundarySelect.append('<option value="' + transb + '">' + transb + '</option>'); 184 } 185 transboundarySelect.select2({ 186 theme: 'bootstrap-5', 187 width: '100%', 188 }); 189 if (!isExternal) { 190 $('#spinner').hide(); 191 $('#breedSearchForm').show(); 192 $('#searchBreedMessage').show(); 193 } 194 } 195 }); 196} 197 198var doBreedSearch = function () {
199 // Logica di instradamento originale (anche se qui viene guidata dai select individualmente) 200 $('#spinner').show(); 201 $('#profileCard').hide(); 202 $('#missingBreeds').hide(); 203 $("#renderBreedsList").empty(); 204 $('#searchBreedMessage').hide(); 205} 206 207var getTransboundaryRisk = function () { 208 $('#spinner').show(); 209 $('#profileCard').hide(); 210 $('#transboundaryTableFields').hide(); 211 $('#missingBreeds').hide(); 212 $('#transboundaryTable').hide(); 213 214 var selectedSpecies = $('#specieSelect').val(); 215 var selectedTransboundary = $('#transboundarySelect').val(); 216 217 if (specieVal != 'all' && specieVal != undefined && specieVal != '') selectedSpecies = specieVal; 218 if (transboundaryVal != 'all' && transboundaryVal != undefined && transboundaryVal != '') selectedTransboundary = transboundaryVal; 219 220 if (!selectedSpecies || !selectedTransboundary) { 221 $('#spinner').hide(); 222 return; 223 } 224 225 const FIREBASE_ENTRY_POINT = ENVIRONMENT_TABLEAU + "/RiskStatusAndTrendTransboundary/RiskStatus.json"; 226 227 $.getJSON(FIREBASE_ENTRY_POINT, function (trendArray) { 228 var table = $('#transboundaryTable'); 229 table.empty(); 230 231 var count = 0; 232 var numbCountriesReportingBreeds = 0; 233 var numberCountriesReportingPopulationData = 0; 234 235 for (var i in trendArray) { 236 if (trendArray.hasOwnProperty(i)) { 237 if (selectedSpecies == trendArray[i]["SPECIES"] && selectedTransboundary == trendArray[i]["TRANSBOUNDARY"]) { 238 239 numbCountriesReportingBreeds++; 240 241 if (trendArray[i]["LOCALBREEDPOPULATIONMINSIZE"] != "" || trendArray[i]["LOCALBREEDPOPULATIONMAXSIZE"] != "" || trendArray[i]["LOCALBREEDINGFEMALE"] != "" || trendArray[i]["LOCALBREEDINGMALE"] != "" || trendArray[i]["LOCALBREEDPERCENTAGEOFFEMALEBREDPURE"] != "") { 242 numberCountriesReportingPopulationData++; 243 } 244 245 var transboundaryRisk = calculateRisk(trendArray[i]["RISK"]); 246 var breedRisk = calculateRisk(trendArray[i]["LOCALBREEDRISK"]); 247 var trend = calculateRiskTrend(trendArray[i]["LOCALBREEDTREND"]); 248 249 setField('card_transboundary_breed', trendArray[i]["TRANSBOUNDARY"]); 250 setField('card_species', trendArray[i]["SPECIES"]); 251 setField('card_breed_type', trendArray[i]["TYPE"]); 252 setField('card_geo_classification', trendArray[i]["GEOCLASSIFICATION"]); 253 setField('card_number_of_countries_reporting_the_breed', numbCountriesReportingBreeds); 254 setField('card_number_of_countries_reporting_the_population_data', numberCountriesReportingPopulationData); 255 256 var estimatePopulationSize = "NA"; 257 if (trendArray[i]["POPULATION"] > -1) { 258 estimatePopulationSize = trendArray[i]["POPULATION"]; 259 if (!isNaN(estimatePopulationSize)) estimatePopulationSize = Math.round(estimatePopulationSize); 260 } 261 setField('card_estimated_population_size', estimatePopulationSize); 262 263 var breed_data_sheet_url_local = BREED_DATA_SHEET_URL + "?country=" + trendArray[i]["COUNTRY"] + "&specie=" + trendArray[i]["SPECIES"] + "&breed=" + trendArray[i]["MOSTCOMMONNAME"] + "&callback=transboundarylist&lang=" + LANG; 264 265 table.append( 266 '<tr><td><a href="' + breed_data_sheet_url_local + '" target="_blank" class="fw-bold text-decoration-none">' + trendArray[i]["MOSTCOMMONNAME"] + '</a></td>' + 267 '<td>' + countryMap.get(trendArray[i]["COUNTRY"]) + '</td>' + 268 '<td>' + renameRiskStatus(trendArray[i]["LOCALBREEDRISK"]) + '</td>' + 269 '<td>' + 270 '<div class="risk-outer-circle ' + transboundaryRisk + '">' + 271 '<div class="risk-inner-circle ' + breedRisk + '">' + 272 '<i class="material-icons">' + trend + '</i>' + 273 '</div></div>' + 274 '</td>' + 275 '<td>' + trendArray[i]["LOCALBREEDPOPULATIONMINSIZE"] + '</td>' + 276 '<td>' + trendArray[i]["LOCALBREEDPOPULATIONMAXSIZE"] + '</td>' + 277 '<td>' + trendArray[i]["LOCALBREEDINGFEMALE"] + '</td>' + 278 '<td>' + trendArray[i]["LOCALBREEDINGMALE"] + '</td>' + 279 '<td>' + trendArray[i]["LOCALBREEDPERCENTAGEOFFEMALEBREDPURE"] + '</td></tr>' 280 ); 281 count++; 282 } 283 } 284 } 285 286 if (count === 0) { 287 $('#missingBreeds').show(); 288 } else { 289 $('#profileCard').show(); 290 $('#transboundaryTableFields').show(); 291 $('#transboundaryTable').show(); 292 $('#searchBreedMessage').hide(); 293 } 294 $('#spinner').hide(); 295 }); 296} 297 298var setField = function (id, value) { 299 var str = checkValue(value) ? value : "-"; 300 $('#' + id).text(str); 301} 302 303var checkValue = function (value) { 304 return (!!value && value != "" && typeof value != "undefined"); 305} 306 307var renameRiskStatus = function (valRisk) { 308 if (valRisk) { 309 switch (valRisk) { 310 case "notAtRisk": return i18nData[LANG]?.['RiskStatus']?.['notAtRisk'] || "Not at Risk"; 311 case "atRisk": return i18nData[LANG]?.['RiskStatus']?.['atRisk'] || "At Risk"; 312 case "critical": return i18nData[LANG]?.['RiskStatus']?.['critical'] || "Critical"; 313 case "endangered": return i18nData[LANG]?.['RiskStatus']?.['endangered'] || "Endangered"; 314 case "vulnerable": return i18nData[LANG]?.['RiskStatus']?.['vulnerable'] || "Vulnerable"; 315 case "unknown": return i18nData[LANG]?.['RiskStatus']?.['unknown'] || "Unknown"; 316 case "extinct": return i18nData[LANG]?.['RiskStatus']?.['extinct'] || "Extinct"; 317 default: return i18nData[LANG]?.['RiskStatus']?.['unknown'] || "Unknown"; 318 } 319 } 320} 321 322var calculateRisk = function (risk) { 323 if (risk) { 324 switch (risk) { 325 case "notAtRisk": return "green"; 326 case "atRisk": return "amber darken-4"; 327 case "critical": return "amber darken-4"; 328 case "endangered": return "amber darken-4"; 329 case "vulnerable": return "amber darken-4"; 330 case "unknown": return "grey"; 331 case "extinct": return "black"; 332 default: return "grey"; 333 } 334 } 335} 336 337var calculateRiskTrend = function (trend) { 338 if (trend) { 339 switch (trend) { 340 case "increasing": return "trending_up"; 341 case "decreasing": return "trending_down"; 342 case "stable": return "trending_flat"; 343 case "unknown": return ""; 344 default: return ""; 345 } 346 } 347} 348 349function getURL() { 350 var species = $('#specieSelect').val(); 351 var transboundary = $('#transboundarySelect').val(); 352 var param = `?species=${species}&transboundary=${encodeURIComponent(transboundary)}&external=1&lang=${LANG}`; 353 var url = SINGLE_TRANSBOUNDARY_CALLBACK + param; 354 window.open(url, "_blank"); 355} 356 357function translateLabels() { 358 // SEARCH FILTERS 359 $('#specieSelect option:first').text(jQuery.i18n.prop('choose_species')); 360 $('#transboundarySelect option:first').text(jQuery.i18n.prop('choose_transboundary')); 361 $("#speciesLabel").text(`${jQuery.i18n.prop('species')}
361`); 362 $("#transboundaryLabel").text(`${jQuery.i18n.prop('transboundary')}`); 363 364 // title 365 $("#titleLabel").text(`${jQuery.i18n.prop('transboundary_breed_summary')}`); 366 367 // main dialog 368 $("#transboundaryBreed").text(`${jQuery.i18n.prop('transboundary_breed')}:`); 369 $("#species").text(`${jQuery.i18n.prop('species')}:`); 370 $("#breedType").text(`${jQuery.i18n.prop('breed_type')}:`); 371 $("#geoClassification").text(`${jQuery.i18n.prop('geo_classification')}:`); 372 $("#nmbCountriesReporting").text(`${jQuery.i18n.prop('nmb_countries_reporting')}:`); 373 $("#nmbCountriesReportingPopulation").text(`${jQuery.i18n.prop('nmb_countries_reporting_population')}:`); 374 $("#estimatedPopulationSize").text(`${jQuery.i18n.prop('estimated_population_size')}:`); 375 376 $("#mostCommonName").text(`${jQuery.i18n.prop('most_common_name')}`); 377 $("#country").text(`${jQuery.i18n.prop('country')}`); 378 $("#nationalRiskStatus").text(`${jQuery.i18n.prop('national_risk_status')}`); 379 $("#riskLevel").text(`${jQuery.i18n.prop('risk_level')}`); 380 $("#populationSizeMin").text(`${jQuery.i18n.prop('population_size_min')}`); 381 $("#populationSizeMax").text(`${jQuery.i18n.prop('population_size_max')}`); 382 $("#breedingFemale").text(`${jQuery.i18n.prop('breeding_female')}`); 383 $("#breedingMale").text(`${jQuery.i18n.prop('breeding_male')}`); 384 $("#femaleBreedPure").text(`${jQuery.i18n.prop('female_breed_pure')}`); 385 386 // messages 387 $("#selectSpeciesMessage").text(`${jQuery.i18n.prop('select_species_message')}`); 388 $("#noTransboundaryBreedsFound").text(`${jQuery.i18n.prop('no_transboundary_breeds_found')}`); 389 $("#error").text(`${jQuery.i18n.prop('error')}`); 390 $("#profileNotFound").text(`${jQuery.i18n.prop('profile_not_found')}`); 391 392 // modal 393 $("#help").text(`${jQuery.i18n.prop('help')}`); 394 $("#help1").text(`${jQuery.i18n.prop('help_1')}`); 395 $("#help2").text(`${jQuery.i18n.prop('help_2')}`); 396 $("#help3").text(`${jQuery.i18n.prop('help_3')}`); 397 $("#help4").text(`${jQuery.i18n.prop('help_4')}`); 398 $("#help5").text(`${jQuery.i18n.prop('help_5')}`); 399} 400 401var loadI18nLocalData = function () { 402 return new Promise((res, rej) => { 403 $.getJSON('./assets/i18n.json', function (data) { 404 if (data == null || typeof data === 'undefined') rej(null); 405 else res(data); 406 }).fail(() => rej(null)); 407 }); 408} 409 410// ========================================================================= 411// EXPORT LOGIC (CSV & REAL EXCEL VIA BASE64) 412// ========================================================================= 413 414function handleExport(selector, baseFilename) { 415 const format = document.querySelector('input[name="exportFormat"]:checked').value; 416 if (format === 'excel') { 417 export_to_real_xlsx_base64(selector, baseFilename + ".xlsx"); 418 } else { 419 export_to_csv_base64(selector, baseFilename + ".csv"); 420 } 421} 422 423function export_to_real_xlsx_base64(selector, filename) { 424 const table = document.querySelector(selector); 425 if (!table) return; 426 427 // Cloniamo la tabella per ripulirla dalle icone visive non utili nell'excel 428 let cloneTable = table.cloneNode(true); 429 let iconCells = cloneTable.querySelectorAll('td i.material-icons'); 430 iconCells.forEach(icon => { icon.parentNode.innerText = icon.innerText; }); 431 432 const wb = XLSX.utils.table_to_book(cloneTable, { sheet: "Transboundary Summary" }); 433 const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'base64' }); 434 const uri = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + wbout; 435 triggerDownload(uri, filename); 436} 437 438function export_to_csv_base64(selector, filename) { 439 let csv = []; 440 let rows = document.querySelectorAll(selector + " tr"); 441 for (let i = 0; i < rows.length; i++) { 442 let row = [], cols = rows[i].querySelectorAll("td, th"); 443 for (let j = 0; j < cols.length; j++) { 444 // Estrazione del testo base (ignora l'HTML interno come i risk circles) 445 let data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, " ").replace(/"/g, '""').trim(); 446 row.push('"' + data + '"'); 447 } 448 csv.push(row.join(",")); 449 } 450 const csvContent = "\uFEFF" + csv.join("\n"); 451 const encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent);
452 triggerDownload(encodedUri, filename); 453} 454 455function triggerDownload(uri, filename) { 456 const link = document.createElement("a"); 457 link.href = uri; 458 link.style.display = 'none'; 459 link.setAttribute("download", filename); 460 document.body.appendChild(link); 461 link.click(); 462 setTimeout(function () { document.body.removeChild(link); }, 100); 463}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.