javascript:(async function() { function getProperty() { try { const el = document.querySelector('.acct-level-menu-address-single .exclude-translation'); const text = el ? el.innerText : document.body.innerText; if (text.includes("23511")) return "23511 E 2nd"; if (text.includes("23513")) return "23513 E 2nd"; if (text.includes("Myrtlewood")) return "Myrtlewood"; if (text.includes("E Upriver")) return "Brookstone"; if (text.includes("W 2nd")) return "Ascott"; if (text.includes("E 36th") || text.includes("E 37th")) return "Commons"; return "Unknown"; } catch(e) { return "Unknown"; } } const propertyName = getProperty(); const limitInput = prompt("Detected Property: " + propertyName + "\n\nLimit downloads to how many?\n(Leave blank for ALL, click Cancel to stop script)"); if (limitInput === null) return; let maxDownloads = Infinity; if (limitInput.trim() !== "") { const parsed = parseInt(limitInput, 10); if (!isNaN(parsed)) maxDownloads = parsed; } const processedUrls = new Set(); let totalDownloaded = 0; const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms)); alert("Starting process.\nTarget: " + (maxDownloads === Infinity ? "ALL" : maxDownloads) + " files.\n\nPlease keep this tab open."); async function scanAndDownload() { const rows = document.querySelectorAll('tr[ng-repeat="entry in pageData.Entries"]'); const currentTotalRows = rows.length; for (const row of rows) { if (totalDownloaded >= maxDownloads) return { count: currentTotalRows, lastText: "", stop: true }; const dateCell = row.querySelector('td[data-heading-label="Date"]'); const pdfCell = row.querySelector('td[data-heading-label="View Bill PDF"]'); if (!dateCell || !pdfCell || pdfCell.classList.contains('ng-hide')) continue; const linkElement = pdfCell.querySelector('a'); if (!linkElement || !linkElement.href) continue; if (processedUrls.has(linkElement.href)) continue; processedUrls.add(linkElement.href); const rawDate = dateCell.innerText.trim(); const parts = rawDate.split('/'); const cleanDate = parts[2] + "-" + parts[0].padStart(2, '0') + "-" + parts[1].padStart(2, '0'); const safeProp = propertyName.replace(/[^a-z0-9\s-_]/gi, '').trim(); const filename = "Avista - " + safeProp + " - " + cleanDate + ".pdf"; try { const response = await fetch(linkElement.href); const blob = await response.blob(); const blobUrl = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = blobUrl; a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(blobUrl); document.body.removeChild(a); totalDownloaded++; await wait(800); } catch (err) { console.error("Download failed", err); } } const lastRowText = rows.length > 0 ? rows[rows.length - 1].innerText : ""; if (totalDownloaded >= maxDownloads) return { count: currentTotalRows, lastText: lastRowText, stop: true }; return { count: currentTotalRows, lastText: lastRowText, stop: false }; } async function waitForNewRows(previousState) { let attempts = 0; while (attempts < 30) { const rows = document.querySelectorAll('tr[ng-repeat="entry in pageData.Entries"]'); const currentCount = rows.length; const currentLastText = rows.length > 0 ? rows[rows.length - 1].innerText : ""; if (currentCount > previousState.count || currentLastText !== previousState.lastText) { return true; } await wait(500); attempts++; } return false; } let keepGoing = true; let currentState = await scanAndDownload(); if (currentState.stop) keepGoing = false; while (keepGoing) { const allSpans = Array.from(document.querySelectorAll('span.btn-secondary')); const moreButton = allSpans.find(s => s.innerText && s.innerText.toLowerCase().includes('load more') && s.offsetParent !== null); const navWrapper = document.querySelector('.nav-pagination-mobile'); const isHidden = navWrapper && navWrapper.classList.contains('ng-hide'); if (moreButton && !isHidden) { moreButton.click(); await waitForNewRows(currentState); currentState = await scanAndDownload(); if (currentState.stop) keepGoing = false; } else { keepGoing = false; } } alert("Job Done!\n\nTotal bills downloaded: " + totalDownloaded); })();