2021// Initialize database
22async function initDatabase() {
23// Create gardens table
24await sqlite.execute(`CREATE TABLE IF NOT EXISTS ${GARDENS_TABLE_NAME} (
Gardenonindex.html24 matches
488
489// Load all gardens
490async function loadGardens() {
491try {
492const response = await fetch('/api/gardens');
520
521// Load current garden and its plants
522async function loadCurrentGarden() {
523if (!currentGarden) return;
524
532
533// Fetch plants for current garden
534async function fetchPlants() {
535if (!currentGarden) {
536plants = [];
551
552// Render plants on the map and in the list
553function renderPlants() {
554// Clear existing plants (but preserve placeholder)
555gardenMap.querySelectorAll('.plant:not(.placeholder)').forEach(el => el.remove());
628
629// Create a new garden
630async function createGarden() {
631const name = newGardenNameInput.value.trim();
632const width = parseInt(newGardenWidthInput.value);
674
675// Update current garden settings
676async function updateGardenSettings() {
677if (!currentGarden) return;
678
722
723// Delete current garden
724async function deleteGarden() {
725if (!currentGarden) return;
726
759
760// Create a placeholder plant on the map
761function createPlaceholderPlant(x, y) {
762// Remove existing placeholder if any
763removePlaceholderPlant();
792
793// Remove placeholder plant from the map
794function removePlaceholderPlant() {
795if (placeholderPlant && placeholderPlant.element) {
796placeholderPlant.element.remove();
800
801// Select a plant to edit
802function selectPlant(plant) {
803// Cancel move mode if active
804if (isMovingPlant) {
833
834// Clear the form
835function clearForm() {
836// Remove placeholder plant if it exists
837removePlaceholderPlant();
859
860// Start move mode
861function startMoveMode() {
862if (!selectedPlant) {
863alert('Please select a plant to move.');
873
874// Cancel move mode
875function cancelMoveMode() {
876isMovingPlant = false;
877mapInstructions.textContent = 'Tap anywhere on the map to add a plant';
882
883// Move plant to new position
884function movePlantTo(x, y) {
885if (!selectedPlant) return;
886
906
907// Add a new plant at the clicked position
908function addPlantAt(x, y) {
909if (!currentGarden) {
910alert('Please select a garden first.');
937
938// Save plant data
939async function savePlant(plantData) {
940if (!currentGarden) {
941alert('Please select a garden first.');
984
985// Update placeholder plant when diameter changes
986function updatePlaceholderPlant() {
987if (placeholderPlant && placeholderPlant.element) {
988const newDiameter = parseFloat(plantDiameterInput.value) || 50;
994
995// Delete a plant
996async function deletePlant(id) {
997if (!confirm('Are you sure you want to delete this plant?')) {
998return;
1020}
1021
1022// Modal functions
1023function openGardenSettingsModal() {
1024if (!currentGarden) {
1025alert('Please select a garden first.');
1033}
1034
1035function closeGardenSettingsModal() {
1036gardenSettingsModal.style.display = 'none';
1037}
1038
1039function openNewGardenModal() {
1040newGardenNameInput.value = '';
1041newGardenWidthInput.value = 700;
1044}
1045
1046function closeNewGardenModal() {
1047newGardenModal.style.display = 'none';
1048}
1176
1177// Initialize
1178async function initialize() {
1179await loadGardens();
1180}
Gardenonadmin.html4 matches
241
242// Fetch database info
243async function fetchDatabaseInfo() {
244try {
245const response = await fetch('/api/admin/db');
257
258// Render database info
259function renderDatabaseInfo() {
260if (!dbData) return;
261
299
300// Render a single table
301function renderTable(tableData, elements) {
302if (!tableData) return;
303
368
369// Toggle between table and JSON view
370function toggleView() {
371isJsonView = !isJsonView;
372
thirdTimerutils.ts2 matches
4* @returns {string} Formatted time string
5*/
6export function formatTime(seconds: number): string {
7const hours = Math.floor(seconds / 3600);
8const minutes = Math.floor((seconds % 3600) / 60);
24* @returns {string} Formatted duration string (e.g., "30s", "5m", "2h 30m")
25*/
26export function formatMinutes(minutes: number): string {
27if (minutes < 1) return `${Math.round(minutes * 60)}s`;
28if (minutes < 60) return `${Math.round(minutes)}m`;
thirdTimerTimerDisplay.tsx1 match
16}
1718export function TimerDisplay({
19state,
20currentSessionTime,
openHeartProtocolmain.tsx6 matches
57};
5859export default async function fetch(request: Request) {
60console.log(`Received ${request.method} request to ${request.url}`);
61if (request.method === "GET") {
70}
7172function error(text: string, code = 400) {
73console.log(`Error response: ${text} (${code})`);
74return new Response(text, { status: code });
75}
7677async function handleGet(request: Request) {
78console.log("Handling GET request");
79const [domain, ...uidParts] = url(request).pathname.slice(1).split("/");
105}
106107function url(request: Request) {
108return new URL(request.url);
109}
110111async function handlePost(request: Request) {
112console.log("Handling POST request");
113const urlObject = url(request);
146}
147148function ensureEmoji(emoji: string) {
149const segments = Array.from(new Intl.Segmenter("en", { granularity: "grapheme" }).segment(emoji.trim()));
150const parsedEmoji: string | null = segments.length > 0 ? segments[0].segment : null;
openHeartProtocolPOST.tsx1 match
1// Send an emoji
23export default async function post() {
4const urls = [
5"https://openheart.val.run/charmaineklee.com/OpenHeart",
146};
147148async function extractPdfTextNative(
149data: ArrayBuffer,
150fileName: string,
173}
174175async function callOpenAI(
176openaiInstance: OpenAI,
177systemPrompt: string,
231}
232233async function ingestDocumentForSuggestion(
234input: { documentFile?: File; clientInputSourceDescription: string },
235log: LogEntry[],
257}
258259function generateHtmlShell(initialQuery: string, sourceUrl: string) {
260const escapedQuery = initialQuery.replace(/</g, "<").replace(/>/g, ">");
261return `
286.hamburger-box { width: 30px; height: 22px; display: inline-block; position: relative; }
287.hamburger-inner { display: block; top: 50%; margin-top: -1px; }
288.hamburger-inner, .hamburger-inner::before, .hamburger-inner::after { width: 30px; height: 2px; background-color: #ecf0f1; border-radius: 4px; position: absolute; transition-property: transform; transition-duration: 0.15s; transition-timing-function: ease; }
289.hamburger-inner::before, .hamburger-inner::after { content: ""; display: block; }
290.hamburger-inner::before { top: -8px; }
404</div>
405<script>
406(function() {
407const MAX_SUGGESTION_SELECTIONS = 15;
408445});
446447function navigateToView(viewId, params = {}) {
448currentView = viewId;
449for (const key in views) { views[key].classList.remove('active-view'); }
468}
469470function setupEventListeners() {
471hamburgerToggle.addEventListener('click', () => {
472const isExpanded = sidebar.classList.contains('expanded-mobile') || !sidebar.classList.contains('collapsed');
519}
520521function generateId() { return Date.now().toString(36) + Math.random().toString(36).substring(2); }
522function escapeHtml(unsafe) {
523if (unsafe === null || typeof unsafe === 'undefined') return '';
524return String(unsafe).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
525}
526527function renderDashboard() {
528views.dashboard.innerHTML = \`
529<h1>Dashboard</h1>
541ni_saveAnalysisButton, ni_taskSelectionInfo, ni_resultsSection;
542543function renderNewInquiryView(params = {}) {
544views['new-inquiry'].innerHTML = \`
545<h1>New Inquiry - IDDAE Workflow</h1>
640}
641642function iddae_setUIPhase(phase) {
643iddae_currentPhase = phase;
644ni_submitButton.classList.remove('loading');
677}
678679async function ni_handleIDDAESubmit(event) {
680event.preventDefault();
681ni_clearStatusMessages();
691}
692
693async function iddae_handleUploadAndSuggestTasks() {
694const file = ni_fileInput.files[0];
695if (!file) {
754}
755756async function iddae_handleFinalAnalysis() {
757const legalTaskQuery = ni_customLegalTaskQueryInput.value.trim();
758if (!legalTaskQuery) {
809}
810811function ni_addStatusMessage(message, type = 'info') {
812const entry = document.createElement('div');
813entry.className = \`status-entry \${type}\`;
817}
818819function ni_clearStatusMessages() {
820if(ni_statusContainer) ni_statusContainer.innerHTML = '';
821}
822823function ni_populateSuggestedTasks(groupedSuggestions = {}) {
824ni_suggestedTasksListDiv.innerHTML = '';
825updateTaskSelectionInfo();
892}
893894function handleGroupCheckboxChange(event) {
895const groupCheckbox = event.target;
896const category = groupCheckbox.dataset.category;
924}
925
926function updateCustomQueryFromSuggestions() {
927const selectedTasks = [];
928const taskCheckboxes = ni_suggestedTasksListDiv.querySelectorAll('input[type="checkbox"]:checked:not([id^="group-"])');
959}
960
961function updateTaskSelectionInfo(count) {
962if (typeof count === 'undefined') {
963count = ni_suggestedTasksListDiv.querySelectorAll('input[type="checkbox"]:checked:not([id^="group-"])').length;
968}
969970function ni_renderStructuredResults(data) {
971if (!data || !data.request_details) {
972ni_structuredResultsContainer.innerHTML = '<p>No valid analysis data to display.</p>';
1019}
10201021function renderHistoryView() {
1022views.history.innerHTML = \`
1023<h1>History</h1>
1033}
10341035function renderDocumentDetailView(docId) {
1036views['document-detail'].innerHTML = \`
1037<h1>Document Details</h1>
1043}
10441045function renderAnalysisDetailView(analysisId) {
1046views['analysis-detail'].innerHTML = \`
1047<h1>Analysis Details</h1>
1053}
1054
1055function renderSettingsView() {
1056views.settings.innerHTML = \`
1057<h1>Settings</h1>
1084}
10851086export default async function(req: Request) {
1087const openai = new OpenAI();
1088const url = new URL(req.url);
1275}
12761277async function runAnalysisWithProvidedText(
1278analysisInput: { legalTaskQuery: string; documentText: string; inputSourceDescription: string },
1279log: LogEntry[],
cronSiteMonitormain.tsx5 matches
36const NOTIFICATION_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes between notifications for same site
3738async function checkSite(url: string): Promise<SiteStatus> {
39const startTime = Date.now();
40const timestamp = new Date().toISOString();
96}
9798async function getSiteHistory(): Promise<Record<string, SiteHistory>> {
99try {
100return await blob.getJSON("uptime_history") || {};
104}
105106async function updateSiteHistory(history: Record<string, SiteHistory>) {
107await blob.setJSON("uptime_history", history);
108}
109110function shouldNotify(siteHistory: SiteHistory, currentStatus: SiteStatus): boolean {
111// Don't notify if site is up
112if (currentStatus.status === "up") return false;
125}
126127export default async function monitor() {
128console.log(`🔍 Starting uptime check for ${SITES_TO_MONITOR.length} sites...`);
129
pt-sandboxmain.ts2 matches
13};
1415function addWaterBodiesToMap(map: TownMap): TownMap {
16// Create a deep copy of the input map
17const newMap = map.map((row) => [...row]);
62}
6364function townMapGenerator({
65width = defaultMapSize.width,
66height = defaultMapSize.height,