2024-11-05 08:34:57 -05:00
|
|
|
(() => {
|
|
|
|
let candidates;
|
2024-11-05 11:25:11 -05:00
|
|
|
let parties;
|
|
|
|
let states;
|
|
|
|
let headerContainer = document.querySelector('div.article-block:nth-child(7)');
|
|
|
|
headerContainer.innerHTML = '';
|
|
|
|
headerContainer.insertAdjacentHTML('afterend', `<table class="heading h3 competitive en president svelte-1gkg98x"><thead><tr><th>Name</th><th>Party</th><th>Votes</th></tr></thead><tbody id="table-body"></tbody></table><div id="state-container" style="display: grid; grid-template-columns:repeat(4, 1fr); gap: 10px;"></div>`);
|
2024-11-05 08:34:57 -05:00
|
|
|
const {
|
|
|
|
fetch: originalFetch
|
|
|
|
} = window;
|
|
|
|
window.fetch = async (...args) => {
|
|
|
|
let [resource, config] = args;
|
|
|
|
let response = await originalFetch(resource, config);
|
|
|
|
if (!response.ok) {
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
const f = response.url.split('/').pop();
|
|
|
|
if (f === "metadata.json") {
|
|
|
|
const metadata = await response.json();
|
2024-11-05 11:25:11 -05:00
|
|
|
states = new Map(metadata.geo.map((c) => [c.uid, c.name]))
|
|
|
|
parties = new Map(metadata.parties.map((c) => [c.code, c.name]));
|
|
|
|
candidates = new Map(metadata.candidates.map((c) => [c.uid, [c.fullName, parties.get(c.candidateRaces[0].majorParty)]]));
|
2024-11-05 08:34:57 -05:00
|
|
|
} else if (f === "president.json") {
|
|
|
|
|
|
|
|
const president = await response.json();
|
|
|
|
let data = president[0]["state_electionTypes"].map((t) => t.state.officeRaces[0].candidateVotes.map((o) => {
|
|
|
|
return {
|
2024-11-05 11:25:11 -05:00
|
|
|
"name": (candidates) ? candidates.get(o.candidate) : [o.candidate, "?"],
|
2024-11-05 08:34:57 -05:00
|
|
|
"votes": o.totalVote
|
|
|
|
};
|
|
|
|
})).reduce((acc, current) => {
|
|
|
|
current.forEach((candidate) => {
|
|
|
|
const existingCandidate = acc.find((c) => c.name === candidate.name);
|
|
|
|
if (existingCandidate) {
|
|
|
|
existingCandidate.votes += candidate.votes;
|
|
|
|
} else {
|
|
|
|
acc.push(candidate);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return acc;
|
|
|
|
}, []);
|
|
|
|
|
2024-11-05 11:25:11 -05:00
|
|
|
let stateVotes = president[0]["state_electionTypes"].map((t) => {
|
|
|
|
return {
|
|
|
|
"state": (states) ? states.get(t.state.uid) : t.uid,
|
|
|
|
"current": t.state.officeRaces[0].officeVotes[0].totalVote,
|
|
|
|
"expected": t.state.officeRaces[0].officeVotes[0].totalExpectedVote,
|
|
|
|
"candidates": t.state.officeRaces[0].candidateVotes.map((o) => {
|
|
|
|
return {
|
|
|
|
"name": (candidates) ? candidates.get(o.candidate) : [o.candidate, "?"],
|
|
|
|
"votes": o.totalVote
|
|
|
|
};
|
|
|
|
})
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2024-11-05 08:34:57 -05:00
|
|
|
if (data.length > 0) {
|
|
|
|
let tableBody = document.getElementById('table-body');
|
|
|
|
tableBody.innerHTML = '';
|
2024-11-05 11:34:50 -05:00
|
|
|
data.sort((a, b) => b.votes - a.votes).forEach((row, index) => {
|
2024-11-05 08:34:57 -05:00
|
|
|
let rowElement = tableBody.insertRow();
|
2024-11-05 11:25:11 -05:00
|
|
|
rowElement.setAttribute('class', `with-state-links row-${index} svelte-woitu6 first-poll-close-row`);
|
2024-11-05 08:34:57 -05:00
|
|
|
let nameCell = rowElement.insertCell();
|
2024-11-05 11:25:11 -05:00
|
|
|
nameCell.setAttribute('class', `state en svelte-woitu6`);
|
|
|
|
let partyCell = rowElement.insertCell();
|
|
|
|
partyCell.setAttribute('class', `state en svelte-woitu6`);
|
2024-11-05 08:34:57 -05:00
|
|
|
let votesCell = rowElement.insertCell();
|
2024-11-05 11:25:11 -05:00
|
|
|
votesCell.setAttribute('class', `state en svelte-woitu6`);
|
|
|
|
nameCell.textContent = row.name[0];
|
|
|
|
partyCell.textContent = row.name[1];
|
2024-11-05 08:34:57 -05:00
|
|
|
votesCell.textContent = row.votes;
|
|
|
|
});
|
|
|
|
}
|
2024-11-05 11:25:11 -05:00
|
|
|
|
|
|
|
if (stateVotes.length > 0) {
|
2024-11-05 12:50:05 -05:00
|
|
|
let stateContainer = document.getElementById('state-container');
|
|
|
|
stateContainer.innerHTML = '';
|
|
|
|
stateVotes.forEach((row) => {
|
|
|
|
const table = document.createElement('table');
|
|
|
|
const thead = document.createElement('thead');
|
|
|
|
const headerRow = document.createElement('tr');
|
|
|
|
const headers = [`${row.state}`, 'Party', `Votes Left: ${row.expected - row.current}`];
|
|
|
|
headers.forEach(header => {
|
|
|
|
const th = document.createElement('th');
|
|
|
|
th.textContent = header;
|
|
|
|
headerRow.appendChild(th);
|
|
|
|
});
|
|
|
|
thead.appendChild(headerRow);
|
|
|
|
table.appendChild(thead);
|
2024-11-05 11:25:11 -05:00
|
|
|
|
2024-11-05 12:50:05 -05:00
|
|
|
const tbody = document.createElement('tbody');
|
|
|
|
row.candidates.sort((a, b) => b.votes - a.votes).forEach((candidate, index) => {
|
|
|
|
const rowElement = document.createElement('tr');
|
2024-11-05 11:25:11 -05:00
|
|
|
|
2024-11-05 12:50:05 -05:00
|
|
|
const nameCell = document.createElement('td');
|
|
|
|
nameCell.textContent = candidate.name[0];
|
|
|
|
rowElement.appendChild(nameCell);
|
2024-11-05 11:25:11 -05:00
|
|
|
|
2024-11-05 12:50:05 -05:00
|
|
|
const partyCell = document.createElement('td');
|
|
|
|
partyCell.textContent = candidate.name[1];
|
|
|
|
rowElement.appendChild(partyCell);
|
2024-11-05 11:25:11 -05:00
|
|
|
|
2024-11-05 12:50:05 -05:00
|
|
|
const votesCell = document.createElement('td');
|
|
|
|
votesCell.textContent = candidate.votes;
|
|
|
|
rowElement.appendChild(votesCell);
|
|
|
|
|
|
|
|
tbody.appendChild(rowElement);
|
|
|
|
});
|
|
|
|
table.appendChild(tbody);
|
|
|
|
stateContainer.appendChild(table);
|
2024-11-05 11:25:11 -05:00
|
|
|
});
|
|
|
|
}
|
2024-11-05 08:34:57 -05:00
|
|
|
}
|
|
|
|
return response;
|
|
|
|
};
|
|
|
|
})();
|