summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/calendar-sync-state.el2
-rw-r--r--data/gcal.org559
-rw-r--r--data/pcal.org826
-rw-r--r--history110
-rw-r--r--init.el12
-rw-r--r--modules/calendar-sync.el252
-rw-r--r--modules/org-agenda-config.el4
-rw-r--r--modules/user-constants.el4
-rw-r--r--tests/test-calendar-sync--expand-weekly.el6
-rw-r--r--tests/test-calendar-sync-properties.el239
-rw-r--r--tests/test-calendar-sync.el79
-rw-r--r--tests/test-integration-recurring-events.el2
-rw-r--r--tests/testutil-calendar-sync.el90
13 files changed, 1647 insertions, 538 deletions
diff --git a/data/calendar-sync-state.el b/data/calendar-sync-state.el
index 0609295d..be2dfe90 100644
--- a/data/calendar-sync-state.el
+++ b/data/calendar-sync-state.el
@@ -1 +1 @@
-((timezone-offset . -28800) (last-sync-time 26916 16431 408271 958000)) \ No newline at end of file
+((timezone-offset . -21600) (calendar-states ("google" :status ok :last-sync (26926 60033 184652 61000) :last-error nil) ("proton" :status ok :last-sync (26926 60014 712405 453000) :last-error nil))) \ No newline at end of file
diff --git a/data/gcal.org b/data/gcal.org
index cc2e2ced..5a743b03 100644
--- a/data/gcal.org
+++ b/data/gcal.org
@@ -1,23 +1,10 @@
-# Google Calendar Events
-
-* Vanessa Homewood's Birthday
-<2025-08-26 Tue>
-This is an event reminder
-
-* Meetali Kerawalla's Birthday
-<2025-08-31 Sun>
-
-* Trash Out
-<2025-08-31 Sun>
-
-* Hallie Parry's Birthday
-<2025-09-02 Tue>
+# Calendar Events
* James massage
-<2025-09-03 Wed 09:30-10:00>
+<2025-09-03 Wed 11:30-12:00>
* Flight to San Francisco (UA 1665)
-<2025-09-04 Thu 15:27-20:08>
+<2025-09-04 Thu 17:27-22:08>
United Airlines flight 1665\nNew Orleans MSY 5:27pm (local time
Location: New Orleans MSY
@@ -25,7 +12,7 @@ Location: New Orleans MSY
<2025-09-07 Sun>
* Flight to New Orleans (UA 246)
-<2025-09-10 Wed 10:01-14:17>
+<2025-09-10 Wed 12:01-16:17>
United Airlines flight 246\nSan Francisco SFO 10:01am (local ti
Location: San Francisco SFO
@@ -33,17 +20,17 @@ Location: San Francisco SFO
<2025-09-14 Sun>
* Marley
-<2025-09-17 Wed 13:00-13:30>
+<2025-09-17 Wed 15:00-15:30>
* Dr. Braddy in Spine Center\, Ochsner Baptist
-<2025-09-19 Fri 11:00-11:45>
+<2025-09-19 Fri 13:00-13:45>
Location: Ochsner Baptist
* Trash Out
<2025-09-21 Sun>
* Laura Arrives at MSY
-<2025-09-21 Sun 15:50-17:00>
+<2025-09-21 Sun 17:50-19:00>
SWA Flight 1849 Sunday 09/21/25 \nPassenger: Laura Smetanick\nD
Location: 1 Terminal Dr\, Kenner\, LA 70062
@@ -55,36 +42,28 @@ Location: 1 Terminal Dr\, Kenner\, LA 70062
This is an event reminder
* Brittni
-<2025-09-24 Wed 11:30-12:00>
+<2025-09-24 Wed 13:30-14:00>
* Review Carrollton Construction Analysis
-<2025-09-24 Wed 13:00-14:30>
+<2025-09-24 Wed 15:00-16:30>
Join with Google Meet: https://meet.google.com/zev-qjor-uhz\n\n
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-09-25 Thu>
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* CVS and liquor store
-<2025-09-25 Thu 08:00-08:30>
+<2025-09-25 Thu 10:00-10:30>
* Trash Out
<2025-09-28 Sun>
* Danneel Meeting @ Martin's
-<2025-09-30 Tue 12:00-14:00>
+<2025-09-30 Tue 14:00-16:00>
Craig Jennings\nHey everyone -- I hope y'all are doing well. I
Location: Martin’s: Wine\, Liquor\, Beer & Deli - New Orleans\, 3827 Baronne
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-10-02 Thu>
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Brady Lester's Birthday
<2025-10-02 Thu>
* Dinner at The Husky with Abby\, Nick
-<2025-10-03 Fri 18:00-20:00>
+<2025-10-03 Fri 20:00-22:00>
Join with Google Meet: https://meet.google.com/zrx-srqr-mkt\n\n
* Prisca Weem's Birthday
@@ -94,28 +73,24 @@ Join with Google Meet: https://meet.google.com/zrx-srqr-mkt\n\n
<2025-10-05 Sun>
* Martin\, GC\, Kelly
-<2025-10-07 Tue 12:00-13:00>
-
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-10-09 Thu>
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+<2025-10-07 Tue 14:00-15:00>
* Harmick/Vahagn <> Craig catch up
-<2025-10-09 Thu 08:00-08:40>
+<2025-10-09 Thu 10:00-10:40>
Hi Craig<br><br>Thanks again for agreeing to meet with us<br><b
* Call Mom
-<2025-10-09 Thu 10:00-11:00>
+<2025-10-09 Thu 12:00-13:00>
Testing where the notes go....
* Amy pain management for Christine
-<2025-10-10 Fri 09:40-10:10>
+<2025-10-10 Fri 11:40-12:10>
* Trash Out
<2025-10-12 Sun>
* Craig/Arusyak Chat
-<2025-10-13 Mon 09:30-10:30>
+<2025-10-13 Mon 11:30-12:30>
\n~-~-~-~-~-~-~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~
* Foursevens Quark Onibi Debut
@@ -126,62 +101,52 @@ This is an event reminder
<2025-10-14 Tue>
* Dr. Braddy -- Pain Mgmt
-<2025-10-14 Tue 11:30-12:15>
-
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-10-16 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+<2025-10-14 Tue 13:30-14:15>
* Post Office: Check to Teresa
-<2025-10-16 Thu 09:00-09:30>
+<2025-10-16 Thu 11:00-11:30>
* CVS: Pick up Your and Xtine Prescriptions
-<2025-10-16 Thu 09:30-10:00>
+<2025-10-16 Thu 11:30-12:00>
* French Truck: Coffee / Lunch
-<2025-10-16 Thu 10:00-10:30>
+<2025-10-16 Thu 12:00-12:30>
* Walk Back
-<2025-10-16 Thu 10:30-11:00>
+<2025-10-16 Thu 12:30-13:00>
* Call with AJ Fudge
-<2025-10-16 Thu 11:00-12:00>
-
-* Pete's Pirate Life Drop
-<2025-10-18 Sat 09:00-09:30>
+<2025-10-16 Thu 13:00-14:00>
* GTFO
<2025-10-18 Sat 10:30-11:00>
+* Pete's Pirate Life Drop
+<2025-10-18 Sat 11:00-11:30>
+
* High school reunion 40th
-<2025-10-18 Sat 17:00-17:30>
+<2025-10-18 Sat 19:00-19:30>
-* Baby Fart Day
+* Trash Out
<2025-10-19 Sun>
-Making it an official all-day event. Attendance mandatory. Loca
-* Trash Out
+* Baby Fart Day
<2025-10-19 Sun>
+Making it an official all-day event. Attendance mandatory. Loca
* Daniel Pham's birthday
<2025-10-22 Wed>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-10-23 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* John Smetanick's Birthday
<2025-10-24 Fri>
This is an event reminder
* Reminder: Arrange for Tile Delivery
-<2025-10-24 Fri 07:00-07:30>
+<2025-10-24 Fri 09:00-09:30>
On Wed Sept 24th we received a call from the tile place who sai
* Danneel Street Project Meeting
-<2025-10-24 Fri 08:00-09:00>
+<2025-10-24 Fri 10:00-11:00>
Craig\,<br><br>Jeff and I are both available tomorrow morning f
Location: 3824 Nashville Ave\, New Orleans\, LA 70125\, USA
@@ -195,73 +160,68 @@ Location: 3824 Nashville Ave\, New Orleans\, LA 70125\, USA
<2025-10-26 Sun>
* Phone Meeting with Arusyak
-<2025-10-26 Sun 08:00-09:00>
+<2025-10-26 Sun 10:00-11:00>
<a href="https://us05web.zoom.us/j/85337619651?pwd=KpBnpye1tahE
* Brunch @ Katie's
-<2025-10-26 Sun 09:30-12:00>
+<2025-10-26 Sun 11:30-14:00>
Join with Google Meet: https://meet.google.com/dny-xfoy-umz\n\n
Location: Katie's\, 3701 Iberville St\, New Orleans\, LA 70119\, USA
* Order and Pick up Lunch for Danneel Project Meeting
-<2025-10-27 Mon 09:00-10:00>
+<2025-10-27 Mon 11:00-12:00>
* Meet with Mark and Jeff
-<2025-10-27 Mon 10:00-10:45>
+<2025-10-27 Mon 12:00-12:45>
Join with Google Meet: https://meet.google.com/cpp-tuxm-kyx\n\n
Location: 3824 Nashville Ave\, New Orleans\, LA 70125\, USA
* Haircut with Ashley @ Aidan Gill
-<2025-10-28 Tue 12:00-12:30>
+<2025-10-28 Tue 14:00-14:30>
This is an event reminder
Location: Aidan Gill For Men\, 2026 Magazine St\, New Orleans\, LA 70130\, U
* Reply to AJ
-<2025-10-29 Wed 09:00-12:00>
+<2025-10-29 Wed 11:00-14:00>
* Change.Yale Lock Batteries
<2025-10-30 Thu>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-10-30 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Answer All Email and Linked In Messages
-<2025-10-30 Thu 11:00-12:00>
+<2025-10-30 Thu 13:00-14:00>
* Work On Disclosures
-<2025-10-30 Thu 12:00-16:30>
+<2025-10-30 Thu 14:00-18:30>
* Fill Out Pre-Check In
-<2025-10-30 Thu 16:30-17:00>
+<2025-10-30 Thu 18:30-19:00>
* Fasting Begins
-<2025-10-30 Thu 17:00-05:00>
+<2025-10-30 Thu 19:00-07:00>
\n1. Do not eat or drink anything for TEN HOURS (10) PRIOR TO T
* Leave for Dr Fernandez Appt
-<2025-10-31 Fri 04:30-05:00>
+<2025-10-31 Fri 06:30-07:00>
* Appt Dr Fernandez
-<2025-10-31 Fri 05:00-06:00>
+<2025-10-31 Fri 07:00-08:00>
\nJeff Hwy Lab - Primary Care Bldg\n\n1401 Jefferson Hwy\nNew O
Location: 1401 Jefferson Ave\, New Orleans\, LA 70115\, USA
* Call with Jonathan Schlutis lawyer
-<2025-10-31 Fri 08:00-08:30>
+<2025-10-31 Fri 10:00-10:30>
* Call with Jon at Reiss
-<2025-10-31 Fri 09:00-09:30>
+<2025-10-31 Fri 11:00-11:30>
* Renew DMV Registration By Mail
-<2025-10-31 Fri 11:00-12:00>
+<2025-10-31 Fri 13:00-14:00>
* File IRS Form 56
-<2025-10-31 Fri 12:00-13:00>
+<2025-10-31 Fri 14:00-15:00>
* Get EIN Tax ID Number
-<2025-10-31 Fri 13:00-14:00>
+<2025-10-31 Fri 15:00-16:00>
* GTFO
<2025-11-01 Sat 10:30-11:00>
@@ -273,37 +233,32 @@ Location: 1401 Jefferson Ave\, New Orleans\, LA 70115\, USA
<2025-11-02 Sun>
* Transit to Meeting
-<2025-11-03 Mon 08:00-08:30>
+<2025-11-03 Mon 10:00-10:30>
* Mark Wetmore
-<2025-11-03 Mon 08:30-09:00>
+<2025-11-03 Mon 10:30-11:00>
This is an event reminder
Location: French Truck Coffee\, 4536 Dryades St\, New Orleans\, LA 70115\, U
* Meeting with AJ
-<2025-11-04 Tue 10:00-11:00>
+<2025-11-04 Tue 12:00-13:00>
* Olle Kjellgren\, MD - Cardiologist
-<2025-11-04 Tue 13:30-14:00>
+<2025-11-04 Tue 15:30-16:00>
Phone: 504-894-2560\n\n\nPlease arrive approximately 15 minutes
Location: 2820 Napoleon Avenue\, Suite 230\, New Orleans LA 70115-6969
* Physical Therapy with Jasmyn Chaisson
-<2025-11-05 Wed 11:30-12:30>
+<2025-11-05 Wed 13:30-14:30>
Phone: 504-894-2002\n
Location: 2820 Napoleon Avenue\, Suite 450\, New Orleans LA 70115-8229
* Phone Call with Craig and Justin
-<2025-11-05 Wed 14:30-15:30>
+<2025-11-05 Wed 16:30-17:30>
<br><br><br><br>Christine Ciarmello<br><br><br><div dir="auto">
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-11-06 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Call Mark Wetmore
-<2025-11-07 Fri 08:30-09:30>
+<2025-11-07 Fri 10:30-11:30>
(504) 799-5697
* GTFO
@@ -316,36 +271,31 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2025-11-09 Sun>
* Call the Probate Court
-<2025-11-10 Mon 12:00-12:30>
+<2025-11-10 Mon 14:00-14:30>
* DEADLINE Send Response to Mark Wetmore
-<2025-11-10 Mon 14:00-14:30>
+<2025-11-10 Mon 16:00-16:30>
* Shower
-<2025-11-11 Tue 09:00-09:30>
+<2025-11-11 Tue 11:00-11:30>
* org-msg improvements
-<2025-11-11 Tue 11:00-14:00>
+<2025-11-11 Tue 13:00-16:00>
* Craig / Ryan
<2025-11-12 Wed 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-11-13 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Call with Jonathan Schultis
-<2025-11-13 Thu 12:00-12:30>
+<2025-11-13 Thu 14:00-14:30>
<p>P: 504.304.7115  Ext. 1002</p><p>D: 504.309.1051</p>\n\nJoin
-* Pick up Prescriptions at CVS
-<2025-11-15 Sat 09:00-10:00>
-
* GTFO
<2025-11-15 Sat 10:30-11:00>
+* Pick up Prescriptions at CVS
+<2025-11-15 Sat 11:00-12:00>
+
* Louisa Housekeeping
<2025-11-15 Sat 11:00-16:00>
@@ -353,83 +303,78 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2025-11-16 Sun>
* Pick Up Prescriptions at CVS
-<2025-11-16 Sun 12:30-13:00>
+<2025-11-16 Sun 14:30-15:00>
* Drive Christine to Clearview
-<2025-11-17 Mon 05:30-06:00>
+<2025-11-17 Mon 07:30-08:00>
* Injection at Clearview
-<2025-11-17 Mon 06:00-06:30>
+<2025-11-17 Mon 08:00-08:30>
* Talk with Shane about Tenants
-<2025-11-17 Mon 14:15-14:45>
+<2025-11-17 Mon 16:15-16:45>
* Finish and Send Email to Jon Schultis
-<2025-11-17 Mon 15:00-16:00>
+<2025-11-17 Mon 17:00-18:00>
* Send Laura Tasks for HB
-<2025-11-17 Mon 18:30-19:00>
+<2025-11-17 Mon 20:30-21:00>
* Pack for Trip
-<2025-11-18 Tue 17:00-18:00>
+<2025-11-18 Tue 19:00-20:00>
* Passport Renewal Work
-<2025-11-18 Tue 18:00-19:00>
+<2025-11-18 Tue 20:00-21:00>
* Driver's License Renewal Work
-<2025-11-18 Tue 19:00-20:00>
+<2025-11-18 Tue 21:00-22:00>
* Arrive at MSY via Uber
-<2025-11-19 Wed 03:30-04:00>
+<2025-11-19 Wed 05:30-06:00>
This is an event reminder
* SW Flight 1435 MSY - LAS
-<2025-11-19 Wed 05:00-08:55>
+<2025-11-19 Wed 07:00-10:55>
WN1435 Boeing 737-800<br><br><br><br><b>Ticket number </b>52621
Location: Louis Armstrong New Orleans International Airport\, 1 Terminal Dr\
* Boarding LGB Flight
-<2025-11-19 Wed 11:30-12:00>
+<2025-11-19 Wed 13:30-14:00>
* SW Flight 2223 LAS - LGB
-<2025-11-19 Wed 12:00-13:15>
+<2025-11-19 Wed 14:00-15:15>
WN2223 Boeing 737-800<br><br><br><br><b>Ticket number </b>52621
Location: Harry Reid International Airport\, 5757 Wayne Newton Blvd\, Las Ve
* Pick up Rental Car at Budget
-<2025-11-19 Wed 13:30-14:00>
+<2025-11-19 Wed 15:30-16:00>
<p>CONFIRMATION 35391712US6<br><br>Ensure you can return car ea
* Drive to Hotel
-<2025-11-19 Wed 14:00-14:30>
+<2025-11-19 Wed 16:00-16:30>
* Arrive at Wyndham Sunset Travelodge
-<2025-11-19 Wed 14:30-15:00>
+<2025-11-19 Wed 16:30-17:00>
Location: 17205 Pacific Coast Hwy\, Sunset Beach\, CA\, 90742
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-11-20 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Tasks
-<2025-11-20 Thu 07:30-08:00>
+<2025-11-20 Thu 09:30-10:00>
Lawyer form\nLease DocuSign \nCVS\nGrocery list for T-day. The
* Shower/Ready
-<2025-11-21 Fri 08:00-09:00>
+<2025-11-21 Fri 10:00-11:00>
* Coffee and Breakfast
-<2025-11-21 Fri 09:00-09:30>
+<2025-11-21 Fri 11:00-11:30>
* Head to Maga's Beach
-<2025-11-21 Fri 09:30-10:00>
+<2025-11-21 Fri 11:30-12:00>
* Call AAA
-<2025-11-21 Fri 10:00-10:30>
+<2025-11-21 Fri 12:00-12:30>
* Call Claire @ Tiempo Escrow
-<2025-11-21 Fri 11:00-11:30>
+<2025-11-21 Fri 13:00-13:30>
Counter offer documents use "Rivera Revocable Trust" but the co
* GTFO
@@ -442,33 +387,53 @@ Counter offer documents use "Rivera Revocable Trust" but the co
<2025-11-23 Sun>
* Arusyak & Craig Chat
-<2025-11-24 Mon 10:00-11:00>
+<2025-11-24 Mon 12:00-13:00>
Join with Google Meet: https://meet.google.com/pxw-chcg-qij\n\n
+* Mail Remaining Boxes & Send Check
+<2025-11-24 Mon 14:00-15:00>
+
+* Upgrade Flights
+<2025-11-24 Mon 15:00-15:30>
+
+* Christine & Craig Catch Up
+<2025-11-24 Mon 16:00-17:00>
+
+* Laundry
+<2025-11-24 Mon 17:00-18:00>
+
+* Tiempo Escrow
+<2025-11-25 Tue 17:00-17:30>
+This is an event reminder
+Location: Tiempo Escrow\, Inc.\, 625 Main St\, Huntington Beach\, CA 92648\,
+
+* Capone's
+<2025-11-25 Tue 20:00-21:00>
+This is an event reminder
+Location: Capone's Italian Cucina\, 19688 Beach Blvd #10\, Huntington Beach\
+
* Pick up Thanksgiving Order at Lagniappe
<2025-11-26 Wed>
* Arrive at LGB
-<2025-11-26 Wed 06:00-06:30>
+<2025-11-26 Wed 08:30-09:00>
This is an event reminder
* Return Rental Car to Budget
-<2025-11-26 Wed 06:30-07:00>
+<2025-11-26 Wed 09:00-09:30>
* SW Flight 4683 LGB - DEN
-<2025-11-26 Wed 08:15-10:30>
+<2025-11-26 Wed 10:15-12:30>
WN4683 Boeing 737-800 \nTicket number 5262105624794\nRapid Rewa
Location: Long Beach Airport\, 4100 Donald Douglas Dr\, Long Beach\, CA 9080
* SW Flight 270 DEN-MSY
-<2025-11-26 Wed 12:10-14:40>
+<2025-11-26 Wed 14:10-16:40>
WN270 Boeing 737-800<br><br><br><br><b>Ticket number </b>526210
Location: Denver International Airport\, 8500 Peña Blvd\, Denver\, CO 80249\
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-11-27 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+* Get EIN#
+<2025-11-28 Fri 16:00-16:30>
* GTFO
<2025-11-29 Sat 10:30-11:00>
@@ -479,15 +444,13 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2025-11-30 Sun>
+* Dr Mejia
+<2025-12-02 Tue 13:00-13:30>
+
* Southwest Flight PVD
-<2025-12-03 Wed 08:40-14:30>
+<2025-12-03 Wed 10:40-16:30>
<br><br><b>confirmation\, </b><b>AV6IHB</b><br><b><br></b><br><
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-12-04 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2025-12-06 Sat 10:30-11:00>
@@ -502,15 +465,10 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
Blake was born in 1999
* Pay healthcare premium for 2026
-<2025-12-10 Wed 12:00-12:30>
-
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-12-11 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+<2025-12-10 Wed 14:00-14:30>
* Marley
-<2025-12-11 Thu 09:00-09:30>
+<2025-12-11 Thu 11:00-11:30>
* Craig / Ryan
<2025-12-12 Fri 10:00-11:00>
@@ -532,11 +490,6 @@ This is an event reminder
* Saradha's Birthday
<2025-12-17 Wed>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-12-18 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Blake Michael's birthday
<2025-12-19 Fri>
@@ -549,11 +502,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2025-12-21 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2025-12-25 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2025-12-27 Sat 10:30-11:00>
@@ -563,10 +511,8 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2025-12-28 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-01-01 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+* Brittni
+<2025-12-30 Tue 14:30-15:00>
* GTFO
<2026-01-03 Sat 10:30-11:00>
@@ -578,18 +524,13 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-01-04 Sun>
* Amy Oregon
-<2026-01-06 Tue 08:20-08:50>
+<2026-01-06 Tue 10:20-10:50>
* New Patient with Lynsi Blanchard\, PA-C
-<2026-01-07 Wed 11:30-12:00>
+<2026-01-07 Wed 13:30-14:00>
Arrival Location: BAPC SLEEP CLINIC\nPhone: 504-842-4910\n\n\nP
Location: 2820 Napoleon Ave\, Ste 590\, New Orleans LA 70115-8209
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-01-08 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-01-10 Sat 10:30-11:00>
@@ -603,11 +544,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-01-12 Mon 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-01-15 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-01-17 Sat 10:30-11:00>
@@ -617,11 +553,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-01-18 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-01-22 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-01-24 Sat 10:30-11:00>
@@ -635,11 +566,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-01-28 Wed>
This is an event reminder
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-01-29 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Cesar Birthday
<2026-01-29 Thu 10:00-10:30>
Join with Google Meet: https://meet.google.com/hgw-ceaa-mfa\n\n
@@ -653,19 +579,14 @@ Join with Google Meet: https://meet.google.com/hgw-ceaa-mfa\n\n
* Louisa Housekeeping
<2026-01-31 Sat 11:00-16:00>
-* Mom and Johns Anniversary
-<2026-02-01 Sun>
-
* Trash Out
<2026-02-01 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-02-05 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+* Mom and Johns Anniversary
+<2026-02-01 Sun>
* Nine Inch Nails
-<2026-02-05 Thu 17:00-19:00>
+<2026-02-05 Thu 19:00-21:00>
Nine Inch Nails bring the Peel It Back Tour 2026 to New Orleans
Location: Smoothie King Center\, 1501 Dave Dixon Dr Space 101-102\, New Orle
@@ -678,11 +599,6 @@ Location: Smoothie King Center\, 1501 Dave Dixon Dr Space 101-102\, New Orle
* Trash Out
<2026-02-08 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-02-12 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Craig / Ryan
<2026-02-12 Thu 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
@@ -696,11 +612,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
* Trash Out
<2026-02-15 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-02-19 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Sara Essex Bradley Birthday
<2026-02-21 Sat>
@@ -714,12 +625,7 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-02-22 Sun>
* Bri
-<2026-02-23 Mon 10:15-10:45>
-
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-02-26 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+<2026-02-23 Mon 12:15-12:45>
* GTFO
<2026-02-28 Sat 10:30-11:00>
@@ -727,17 +633,12 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Louisa Housekeeping
<2026-02-28 Sat 11:00-16:00>
-* Anniversary
-<2026-03-01 Sun>
-This is an event reminder
-
* Trash Out
<2026-03-01 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-03-05 Thu>
+* Anniversary
+<2026-03-01 Sun>
This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
* GTFO
<2026-03-07 Sat 10:30-11:00>
@@ -748,11 +649,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-03-08 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-03-12 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Craig / Ryan
<2026-03-12 Thu 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
@@ -773,11 +669,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
<2026-03-15 Sun>
Join with Google Meet: https://meet.google.com/myx-kkcm-nav\n\n
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-03-19 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-03-21 Sat 10:30-11:00>
@@ -791,11 +682,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-03-25 Wed>
------------\nFrom:Lauren Peterson\nSent:Monday\, March 25\, 20
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-03-26 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Gracie's Birthday
<2026-03-27 Fri>
This is an event reminder
@@ -819,11 +705,6 @@ This is an event reminder
* Sanjeevani Bhardwaj's Birthday
<2026-04-02 Thu>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-04-02 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-04-04 Sat 10:30-11:00>
@@ -833,11 +714,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-04-05 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-04-09 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Anniversary: SF
<2026-04-11 Sat>
Christine and I got married in City Hall this day
@@ -855,11 +731,6 @@ Christine and I got married in City Hall this day
<2026-04-12 Sun 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-04-16 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-04-18 Sat 10:30-11:00>
@@ -869,11 +740,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-04-19 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-04-23 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-04-25 Sat 10:30-11:00>
@@ -883,11 +749,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-04-26 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-04-30 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Change.Yale Lock Batteries
<2026-04-30 Thu>
@@ -900,11 +761,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-05-03 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-05-07 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-05-09 Sat 10:30-11:00>
@@ -918,11 +774,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-05-12 Tue 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-05-14 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-05-16 Sat 10:30-11:00>
@@ -932,11 +783,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-05-17 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-05-21 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-05-23 Sat 10:30-11:00>
@@ -946,11 +792,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-05-24 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-05-28 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-05-30 Sat 10:30-11:00>
@@ -960,11 +801,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-05-31 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-06-04 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-06-06 Sat 10:30-11:00>
@@ -974,11 +810,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-06-07 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-06-11 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Craig / Ryan
<2026-06-12 Fri 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
@@ -992,11 +823,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
* Trash Out
<2026-06-14 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-06-18 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-06-20 Sat 10:30-11:00>
@@ -1006,11 +832,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-06-21 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-06-25 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Christine's Birthday
<2026-06-27 Sat>
Born this day in 1968
@@ -1024,11 +845,6 @@ Born this day in 1968
* Trash Out
<2026-06-28 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-07-02 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-07-04 Sat 10:30-11:00>
@@ -1038,11 +854,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-07-05 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-07-09 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-07-11 Sat 10:30-11:00>
@@ -1067,11 +878,6 @@ This is an event reminder
<2026-07-15 Wed>
This is an event reminder
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-07-16 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-07-18 Sat 10:30-11:00>
@@ -1081,11 +887,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-07-19 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-07-23 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-07-25 Sat 10:30-11:00>
@@ -1095,11 +896,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-07-26 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-07-30 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Change.Yale Lock Batteries
<2026-07-30 Thu>
@@ -1119,11 +915,6 @@ This is an event reminder
* Laura Smetanick's birthday
<2026-08-05 Wed>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-08-06 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-08-08 Sat 10:30-11:00>
@@ -1140,11 +931,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-08-12 Wed 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-08-13 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-08-15 Sat 10:30-11:00>
@@ -1154,11 +940,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-08-16 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-08-20 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-08-22 Sat 10:30-11:00>
@@ -1175,11 +956,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-08-26 Wed>
This is an event reminder
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-08-27 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-08-29 Sat 10:30-11:00>
@@ -1195,11 +971,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Hallie Parry's Birthday
<2026-09-02 Wed>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-09-03 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-09-05 Sat 10:30-11:00>
@@ -1209,11 +980,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-09-06 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-09-10 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Craig / Ryan
<2026-09-12 Sat 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
@@ -1227,11 +993,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
* Trash Out
<2026-09-13 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-09-17 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-09-19 Sat 10:30-11:00>
@@ -1244,11 +1005,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Michelle Sartor's birthday
<2026-09-22 Tue>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-09-24 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Liz Balsam's Birthday
<2026-09-24 Thu>
This is an event reminder
@@ -1262,11 +1018,6 @@ This is an event reminder
* Trash Out
<2026-09-27 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-10-01 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Brady Lester's Birthday
<2026-10-02 Fri>
@@ -1276,16 +1027,11 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Louisa Housekeeping
<2026-10-03 Sat 11:00-16:00>
-* Prisca Weem's Birthday
-<2026-10-04 Sun>
-
* Trash Out
<2026-10-04 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-10-08 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
+* Prisca Weem's Birthday
+<2026-10-04 Sun>
* GTFO
<2026-10-10 Sat 10:30-11:00>
@@ -1303,11 +1049,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
* Susan Moynihan's Birthday
<2026-10-14 Wed>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-10-15 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-10-17 Sat 10:30-11:00>
@@ -1321,11 +1062,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
<2026-10-19 Mon>
Making it an official all-day event. Attendance mandatory. Loca
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-10-22 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Daniel Pham's birthday
<2026-10-22 Thu>
@@ -1342,11 +1078,6 @@ This is an event reminder
* Trash Out
<2026-10-25 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-10-29 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Change.Yale Lock Batteries
<2026-10-30 Fri>
@@ -1359,11 +1090,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-11-01 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-11-05 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-11-07 Sat 10:30-11:00>
@@ -1373,11 +1099,6 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-11-08 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-11-12 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* Craig / Ryan
<2026-11-12 Thu 10:00-11:00>
Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
@@ -1391,11 +1112,6 @@ Join with Google Meet: https://meet.google.com/kgb-ngmj-tez\nOr
* Trash Out
<2026-11-15 Sun>
-* Lagniappe Bakehouse Is Open 8 AM–1 PM
-<2026-11-19 Thu>
-This is an event reminder
-Location: 1825 Euterpe St\, New Orleans\, LA 70113
-
* GTFO
<2026-11-21 Sat 10:30-11:00>
@@ -1404,3 +1120,12 @@ Location: 1825 Euterpe St\, New Orleans\, LA 70113
* Trash Out
<2026-11-22 Sun>
+
+* GTFO
+<2026-11-28 Sat 10:30-11:00>
+
+* Louisa Housekeeping
+<2026-11-28 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-29 Sun>
diff --git a/data/pcal.org b/data/pcal.org
new file mode 100644
index 00000000..c76ae2d0
--- /dev/null
+++ b/data/pcal.org
@@ -0,0 +1,826 @@
+# Calendar Events
+
+* Lisa Housekeeping
+<2025-09-06 Sat 11:00-16:00>
+
+* Trash Out
+<2025-09-07 Sun>
+
+* Craig<>Arusyak: sync up
+<2025-09-12 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-09-13 Sat 11:00-16:00>
+
+* Trash Out
+<2025-09-14 Sun>
+
+* Ochsner Baptist Spine Clinic
+<2025-09-19 Fri 13:00-15:00>
+Directions for Baptist - Pain Management\nTurn at Entrance 1 on
+Location: 2820 Napoleon Ave New Orleans LA 70115-6969
+
+* Columns then Osteria Lupo with Nick and Abbey
+<2025-09-19 Fri 19:45-22:00>
+Christine: Hi\, we all have new astrological signs\, so I booke
+Location: 3811 St Charles Ave\, New Orleans\, LA 70115
+
+* Lisa Housekeeping
+<2025-09-20 Sat 11:00-16:00>
+
+* Trash Out
+<2025-09-21 Sun>
+
+* Laura Arrives at MSY
+<2025-09-21 Sun 17:50-19:00>
+SWA Flight 1849 Sunday 09/21/25 \nPassenger: Laura Smetanick\nD
+Location: 1 Terminal Dr\, Kenner\, LA 70062
+
+* Reservations at the Bell
+<2025-09-21 Sun 19:30-20:00>
+Location: 3125 Esplanade Avenue New Orleans\, LA 70119
+
+* Michelle Sartor's birthday
+<2025-09-22 Mon>
+
+* Liz Balsam's Birthday
+<2025-09-24 Wed>
+
+* Craig<>Arusyak: sync up
+<2025-09-26 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-09-27 Sat 11:00-16:00>
+
+* Trash Out
+<2025-09-28 Sun>
+
+* See Paul @ pop up
+<2025-09-28 Sun 14:00-16:00>
+
+* Rosalita's Backyard Tacos at Bud Rip's Old 9th Ward Bar\, 6-9 pm
+<2025-09-30 Tue>
+They are open 6 - 9 pm\nP: (504) 945-5762\nNeighborhood: Faubou
+Location: 900 Piety St. New Orleans\, LA 70117
+
+* Danneel Meeting @ Martin's
+<2025-09-30 Tue 14:00-16:00>
+Craig Jennings\nHey everyone -- I hope y'all are doing well. I
+Location: Martin’s: Wine\, Liquor\, Beer & Deli - New Orleans\, 3827 Baron
+
+* Brady Lester's Birthday
+<2025-10-02 Thu>
+
+* Dinner at The Husky with Abby\, Nick
+<2025-10-03 Fri 20:00-22:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/zrx-srqr-mkt
+
+* Prisca Weem's Birthday
+<2025-10-04 Sat>
+
+* Lisa Housekeeping
+<2025-10-04 Sat 11:00-16:00>
+
+* Trash Out
+<2025-10-05 Sun>
+
+* Ready for Danneel Street Mtg
+<2025-10-07 Tue 13:15-13:45>
+
+* Danneel Project Mtg @ Martin's
+<2025-10-07 Tue 14:00-15:00>
+
+* Call Mom
+<2025-10-07 Tue 16:30-17:00>
+
+* Harmick/Vahagn <> Craig catch up
+<2025-10-09 Thu 19:00-19:40>
+Hi Craig\nThanks again for agreeing to meet with us\nI hope thi
+Location: https://meet.google.com/gzd-jmqo-zmv
+
+* Craig<>Arusyak: sync up
+<2025-10-10 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-10-11 Sat 11:00-16:00>
+
+* Trash Out
+<2025-10-12 Sun>
+
+* Craig/Arusyak Chat
+<2025-10-13 Mon 11:30-12:30>
+\n~-~-~-~-~-~-~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~
+
+* Susan Moynihan's Birthday
+<2025-10-14 Tue>
+
+* Lisa Housekeeping
+<2025-10-18 Sat 11:00-16:00>
+
+* Baby Fart Day
+<2025-10-19 Sun>
+Making it an official all-day event. Attendance mandatory. Loca
+
+* Susan Ruhne's Birthday
+<2025-10-19 Sun>
+
+* Trash Out
+<2025-10-19 Sun>
+
+* Daniel Pham's birthday
+<2025-10-22 Wed>
+
+* Craig<>Arusyak: sync up
+<2025-10-24 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-10-25 Sat 11:00-16:00>
+
+* Trash Out
+<2025-10-26 Sun>
+
+* Arusyak & Craig Chat
+<2025-10-26 Sun 10:00-11:00>
+\n~-~-~-~-~-~-~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~%~!~
+
+* Change.Yale Lock Batteries
+<2025-10-30 Thu>
+
+* Halloween
+<2025-10-31 Fri>
+
+* Lisa Housekeeping
+<2025-11-01 Sat 11:00-16:00>
+
+* Trash Out
+<2025-11-02 Sun>
+
+* Mr. Griffin lawyer
+<2025-11-06 Thu 10:30-11:00>
+8630 Oak Street\nBrides on Oak\, next door neighbor\, address o
+
+* Craig<>Arusyak: sync up
+<2025-11-07 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-11-08 Sat 11:00-16:00>
+
+* Trash Out
+<2025-11-09 Sun>
+
+* Craig / Ryan
+<2025-11-12 Wed 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2025-11-15 Sat 11:00-16:00>
+
+* Trash Out
+<2025-11-16 Sun>
+
+* Craig<>Arusyak: sync up
+<2025-11-21 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-11-22 Sat 11:00-16:00>
+
+* Trash Out
+<2025-11-23 Sun>
+
+* Arusyak & Craig Chat
+<2025-11-24 Mon 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/pxw-chcg-qij
+
+* Lisa Housekeeping
+<2025-11-29 Sat 11:00-16:00>
+
+* Trash Out
+<2025-11-30 Sun>
+
+* Dr Mejia
+<2025-12-02 Tue 13:00-13:30>
+
+* Craig<>Arusyak: sync up
+<2025-12-05 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-12-06 Sat 11:00-16:00>
+
+* Trash Out
+<2025-12-07 Sun>
+
+* Blake Michael's Birthday
+<2025-12-09 Tue>
+Blake was born in 1999
+
+* Craig / Ryan
+<2025-12-12 Fri 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Augusta Baty Birthday
+<2025-12-13 Sat>
+
+* Lisa Housekeeping
+<2025-12-13 Sat 11:00-16:00>
+
+* Trash Out
+<2025-12-14 Sun>
+
+* Saradha's Birthday
+<2025-12-17 Wed>
+
+* Anniversary: The Day I Met Christine
+<2025-12-17 Wed>
+
+* Michael Bradley's Birthday
+<2025-12-18 Thu>
+
+* Blake Michael's birthday
+<2025-12-19 Fri>
+
+* Craig<>Arusyak: sync up
+<2025-12-19 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2025-12-20 Sat 11:00-16:00>
+
+* Trash Out
+<2025-12-21 Sun>
+
+* Christmas Day
+<2025-12-25 Thu>
+
+* Lisa Housekeeping
+<2025-12-27 Sat 11:00-16:00>
+
+* Trash Out
+<2025-12-28 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-01-02 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-01-03 Sat 11:00-16:00>
+
+* Trash Out
+<2026-01-04 Sun>
+
+* Lisa Housekeeping
+<2026-01-10 Sat 11:00-16:00>
+
+* Trash Out
+<2026-01-11 Sun>
+
+* Craig / Ryan
+<2026-01-12 Mon 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Craig<>Arusyak: sync up
+<2026-01-16 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-01-17 Sat 11:00-16:00>
+
+* Trash Out
+<2026-01-18 Sun>
+
+* Lisa Housekeeping
+<2026-01-24 Sat 11:00-16:00>
+
+* Trash Out
+<2026-01-25 Sun>
+
+* Christy Gordon Baty Birthday
+<2026-01-28 Wed>
+
+* Cesar Birthday
+<2026-01-29 Thu>
+
+* Change.Yale Lock Batteries
+<2026-01-30 Fri>
+
+* Craig<>Arusyak: sync up
+<2026-01-30 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Blake and Kat's Anniversary
+<2026-01-31 Sat>
+
+* Lisa Housekeeping
+<2026-01-31 Sat 11:00-16:00>
+
+* Mom and Johns Anniversary
+<2026-02-01 Sun>
+
+* Trash Out
+<2026-02-01 Sun>
+
+* Lisa Housekeeping
+<2026-02-07 Sat 11:00-16:00>
+
+* Trash Out
+<2026-02-08 Sun>
+
+* Craig / Ryan
+<2026-02-12 Thu 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Craig<>Arusyak: sync up
+<2026-02-13 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-02-14 Sat 11:00-16:00>
+
+* Trash Out
+<2026-02-15 Sun>
+
+* Sara Essex Bradley Birthday
+<2026-02-21 Sat>
+
+* Lisa Housekeeping
+<2026-02-21 Sat 11:00-16:00>
+
+* Trash Out
+<2026-02-22 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-02-27 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-02-28 Sat 11:00-16:00>
+
+* Anniversary
+<2026-03-01 Sun>
+
+* Trash Out
+<2026-03-01 Sun>
+
+* Lisa Housekeeping
+<2026-03-07 Sat 11:00-16:00>
+
+* Trash Out
+<2026-03-08 Sun>
+
+* Craig / Ryan
+<2026-03-12 Thu 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Craig<>Arusyak: sync up
+<2026-03-13 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Pi Day!
+<2026-03-14 Sat>
+
+* Lisa Housekeeping
+<2026-03-14 Sat 11:00-16:00>
+
+* Louisa Birthday
+<2026-03-15 Sun>
+
+* Trash Out
+<2026-03-15 Sun>
+
+* Lisa Housekeeping
+<2026-03-21 Sat 11:00-16:00>
+
+* Trash Out
+<2026-03-22 Sun>
+
+* Rajani Ramanathan's Birthday
+<2026-03-25 Wed>
+------------\nFrom:Lauren Peterson\nSent:Monday, March 25, 2013
+
+* Gracie's Birthday
+<2026-03-27 Fri>
+
+* Craig<>Arusyak: sync up
+<2026-03-27 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-03-28 Sat 11:00-16:00>
+
+* Trash Out
+<2026-03-29 Sun>
+
+* Gabi Birthday
+<2026-03-31 Tue>
+
+* POD Return Date
+<2026-04-01 Wed>
+
+* Sanjeevani Bhardwaj's Birthday
+<2026-04-02 Thu>
+
+* Lisa Housekeeping
+<2026-04-04 Sat 11:00-16:00>
+
+* Trash Out
+<2026-04-05 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-04-10 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Anniversary: SF
+<2026-04-11 Sat>
+Christine and I got married in City Hall this day
+
+* Lisa Housekeeping
+<2026-04-11 Sat 11:00-16:00>
+
+* Trash Out
+<2026-04-12 Sun>
+
+* Craig / Ryan
+<2026-04-12 Sun 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2026-04-18 Sat 11:00-16:00>
+
+* Trash Out
+<2026-04-19 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-04-24 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-04-25 Sat 11:00-16:00>
+
+* Trash Out
+<2026-04-26 Sun>
+
+* Change.Yale Lock Batteries
+<2026-04-30 Thu>
+
+* Lisa Housekeeping
+<2026-05-02 Sat 11:00-16:00>
+
+* Trash Out
+<2026-05-03 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-05-08 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-05-09 Sat 11:00-16:00>
+
+* Trash Out
+<2026-05-10 Sun>
+
+* Craig / Ryan
+<2026-05-12 Tue 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2026-05-16 Sat 11:00-16:00>
+
+* Trash Out
+<2026-05-17 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-05-22 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-05-23 Sat 11:00-16:00>
+
+* Trash Out
+<2026-05-24 Sun>
+
+* Lisa Housekeeping
+<2026-05-30 Sat 11:00-16:00>
+
+* Trash Out
+<2026-05-31 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-06-05 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-06-06 Sat 11:00-16:00>
+
+* Trash Out
+<2026-06-07 Sun>
+
+* Craig / Ryan
+<2026-06-12 Fri 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2026-06-13 Sat 11:00-16:00>
+
+* Trash Out
+<2026-06-14 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-06-19 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-06-20 Sat 11:00-16:00>
+
+* Trash Out
+<2026-06-21 Sun>
+
+* Christine's Birthday
+<2026-06-27 Sat>
+Born this day in 1968
+
+* Lisa Housekeeping
+<2026-06-27 Sat 11:00-16:00>
+
+* Trash Out
+<2026-06-28 Sun>
+
+* Sharon Sikora's Birthday
+<2026-06-29 Mon>
+
+* Craig<>Arusyak: sync up
+<2026-07-03 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-07-04 Sat 11:00-16:00>
+
+* Trash Out
+<2026-07-05 Sun>
+
+* Lisa Housekeeping
+<2026-07-11 Sat 11:00-16:00>
+
+* Lucy Nischwitz's birthday
+<2026-07-12 Sun>
+
+* Trash Out
+<2026-07-12 Sun>
+
+* Craig / Ryan
+<2026-07-12 Sun 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Kevin Michael's Birthday
+<2026-07-14 Tue>
+
+* Chase Michael's Birthday
+<2026-07-15 Wed>
+
+* Craig<>Arusyak: sync up
+<2026-07-17 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-07-18 Sat 11:00-16:00>
+
+* Trash Out
+<2026-07-19 Sun>
+
+* Lisa Housekeeping
+<2026-07-25 Sat 11:00-16:00>
+
+* Trash Out
+<2026-07-26 Sun>
+
+* Change.Yale Lock Batteries
+<2026-07-30 Thu>
+
+* Craig<>Arusyak: sync up
+<2026-07-31 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-08-01 Sat 11:00-16:00>
+
+* Trash Out
+<2026-08-02 Sun>
+
+* Vivi Baty Birthday
+<2026-08-04 Tue>
+
+* Laura Smetanick's birthday
+<2026-08-05 Wed>
+
+* Lisa Housekeeping
+<2026-08-08 Sat 11:00-16:00>
+
+* Trash Out
+<2026-08-09 Sun>
+
+* Craig / Ryan
+<2026-08-12 Wed 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Craig<>Arusyak: sync up
+<2026-08-14 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-08-15 Sat 11:00-16:00>
+
+* Trash Out
+<2026-08-16 Sun>
+
+* Lisa Housekeeping
+<2026-08-22 Sat 11:00-16:00>
+
+* Nate Cooper's Birthday
+<2026-08-23 Sun>
+
+* Trash Out
+<2026-08-23 Sun>
+
+* Vanessa Homewood's Birthday
+<2026-08-26 Wed>
+
+* Craig<>Arusyak: sync up
+<2026-08-28 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-08-29 Sat 11:00-16:00>
+
+* Trash Out
+<2026-08-30 Sun>
+
+* Meetali Kerawalla's Birthday
+<2026-08-31 Mon>
+
+* Hallie Parry's Birthday
+<2026-09-02 Wed>
+
+* Lisa Housekeeping
+<2026-09-05 Sat 11:00-16:00>
+
+* Trash Out
+<2026-09-06 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-09-11 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Craig / Ryan
+<2026-09-12 Sat 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2026-09-12 Sat 11:00-16:00>
+
+* Trash Out
+<2026-09-13 Sun>
+
+* Lisa Housekeeping
+<2026-09-19 Sat 11:00-16:00>
+
+* Trash Out
+<2026-09-20 Sun>
+
+* Michelle Sartor's birthday
+<2026-09-22 Tue>
+
+* Liz Balsam's Birthday
+<2026-09-24 Thu>
+
+* Craig<>Arusyak: sync up
+<2026-09-25 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-09-26 Sat 11:00-16:00>
+
+* Trash Out
+<2026-09-27 Sun>
+
+* Brady Lester's Birthday
+<2026-10-02 Fri>
+
+* Lisa Housekeeping
+<2026-10-03 Sat 11:00-16:00>
+
+* Prisca Weem's Birthday
+<2026-10-04 Sun>
+
+* Trash Out
+<2026-10-04 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-10-09 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-10-10 Sat 11:00-16:00>
+
+* Trash Out
+<2026-10-11 Sun>
+
+* Craig / Ryan
+<2026-10-12 Mon 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Susan Moynihan's Birthday
+<2026-10-14 Wed>
+
+* Lisa Housekeeping
+<2026-10-17 Sat 11:00-16:00>
+
+* Trash Out
+<2026-10-18 Sun>
+
+* Baby Fart Day
+<2026-10-19 Mon>
+Making it an official all-day event. Attendance mandatory. Loca
+
+* Susan Ruhne's Birthday
+<2026-10-19 Mon>
+
+* Daniel Pham's birthday
+<2026-10-22 Thu>
+
+* Craig<>Arusyak: sync up
+<2026-10-23 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-10-24 Sat 11:00-16:00>
+
+* Trash Out
+<2026-10-25 Sun>
+
+* Change.Yale Lock Batteries
+<2026-10-30 Fri>
+
+* Halloween
+<2026-10-31 Sat>
+
+* Lisa Housekeeping
+<2026-10-31 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-01 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-11-06 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-11-07 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-08 Sun>
+
+* Craig / Ryan
+<2026-11-12 Thu 10:00-11:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+Location: https://meet.google.com/kgb-ngmj-tez
+
+* Lisa Housekeeping
+<2026-11-14 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-15 Sun>
+
+* Craig<>Arusyak: sync up
+<2026-11-20 Fri 17:00-18:00>
+-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~
+
+* Lisa Housekeeping
+<2026-11-21 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-22 Sun>
+
+* Lisa Housekeeping
+<2026-11-28 Sat 11:00-16:00>
+
+* Trash Out
+<2026-11-29 Sun>
diff --git a/history b/history
index 1e5b6de6..a825ec38 100644
--- a/history
+++ b/history
@@ -4,9 +4,9 @@
(setq savehist-minibuffer-history-variables '(dwim-shell-command-history shell-command-history goto-line-history embark--prompter-history coding-system-history Man-topic-history command-history fontaine-preset-history string-rectangle-history org-read-date-history read-char-history org-roam-node-history consult-imenu--history emms-source-playlist-format-history deadgrep-history read-expression-history eww-prompt-history org-refile-history read-number-history magit-revision-history query-replace-history input-method-history org-tags-history buffer-name-history read-from-kill-ring-history file-name-history mu4e--search-hist consult--line-history minibuffer-history pdf-annot-color-history consult--buffer-history extended-command-history))
(setq dwim-shell-command-history '("extract audio from video"))
(setq goto-line-history '("1"))
-(setq command-history '((cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt") (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log") (cj/kill-buffer-or-bury-alive "*emacs*") (cj/kill-buffer-or-bury-alive "*img-cache*") (cj/kill-buffer-or-bury-alive "*external-open.log*") (helpful-key "p") (dwim-shell-command 1) (execute-extended-command nil "dwim-shell-command") (dwim-shell-commands-menu) (execute-extended-command nil "dwim-shell-commands-menu" "dwim-she") (execute-extended-command nil "dwim-shell-command" "dwim=") (find-file "~/code/dwim-shell-command/dwim-shell-commands.el" t) (helpful-key "\344") (execute-extended-command nil "dwim-shell-commands-menu") (helpful-key "a") (execute-extended-command nil "dwim-shell-commands-menu" "dwim=") (execute-extended-command nil "dwim-shell-command" "dwim-shell-comm") (helpful-key "\303") (wttrin "Huntington Beach, CA") (time-zones) (execute-extended-command nil "time-zones" "timezon") (cj/kill-buffer-or-bury-alive "christine-2025-09-04-henry-jovel-construction-34550.pdf") (cj/kill-buffer-or-bury-alive "expenses-real-estate.org") (find-file "~/projects/jr-estate/event-candidates.org" t) (cj/org-sort-by-todo-and-priority) (execute-extended-command nil "cj/org-sort-by-todo-and-priority") (cj/kill-buffer-or-bury-alive "kelly-pacific-dream-painting.vcf") (find-file "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" t) (cj/kill-buffer-or-bury-alive "todo.org") (cj/kill-buffer-or-bury-alive "claire.vcf") (cj/kill-buffer-or-bury-alive "2025-11-21-10-07-39.txt") (cj/open-file-with-command "masterpdfeditor5") (query-replace "Speaker A" "Craig" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (query-replace "Speaker B" "Claire" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (cj/kill-buffer-or-bury-alive "Notes of The Truth About the World_ Basic Readings - James Rachels.pdf") (pdf-view-position-to-register 113) (bookmark-set nil nil) (execute-extended-command nil "bookmark-set" "book") (cj/kill-buffer-or-bury-alive "org-noter-workflow-spec.org") (find-file "~/.emacs.d/docs/org-noter-workflow-spec.org" t) (cj/kill-buffer-or-bury-alive "early-init.el") (package-upgrade-all t) (execute-extended-command nil "package-upgrade-all" "package-upgra") (cj/kill-buffer-or-bury-alive "gcal.org") (wttrin "New Orleans, LA") (find-file "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " t) (query-replace "Speaker C" "Justin Ratowsky" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (query-replace "Speaker A" "Craig Ratowsky" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (query-replace "Speaker B" "Craig Jennings" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (cj/kill-buffer-or-bury-alive "2025-11-18-18-13-21-email-to-laura-hb-trip-planning.eml")))
+(setq command-history '((calendar-sync-status) (execute-extended-command nil "calendar-sync-status" "calendar-sync") (cj/kill-buffer-or-bury-alive "gcal.org") (calendar-sync-now "proton") (execute-extended-command nil "calendar-sync-now" "calendar-sync") (cj/kill-buffer-or-bury-alive "org-agenda-config.el") (cj/kill-buffer-or-bury-alive "calendar-sync.el") (dired-create-directory "~/archive/magic/Daniel Madison System/") (query-replace #(" on Vimeo" 0 8 (dired-filename t) 8 9 (rear-nonsticky t dired-filename t)) "" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (string-rectangle 201 892 "0") (dired-create-directory "~/archive/magic/Daniel Madison Induction") (dired-create-directory "~/archive/magic/Daniel Madison Expert") (write-file "~/projects/finances/inbox/Danneel-street-hoa-payment.eml" t) (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-Money & Masculinity — Scott Galloway & Ed Elson on What Defines a Man | Prof G Markets.f399.mp4.part") (cj/kill-buffer-or-bury-alive "Malyon Transcript") (malyon-quit) (execute-extended-command nil "malyon-quit" "malyon") (malyon "~/sync/org/text.games/planetfall.1983.z3") (execute-extended-command nil "malyon" "maly") (cj/kill-buffer-or-bury-alive "*eww*") (eww "https://spacenews.com/pentagon-turns-to-government-owned-commercially-operated-satellites-amid-conflict-risks/" nil) (wttrin "Huntington Beach, CA") (query-replace ": " ": " nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (query-replace "Craig:" "Claire: " nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (query-replace "Claire" "Craig Jennings" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (cj/kill-buffer-or-bury-alive "assets") (find-file "~/projects/jr-estate/assets" t) (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt") (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log") (cj/kill-buffer-or-bury-alive "*emacs*") (cj/kill-buffer-or-bury-alive "*img-cache*") (cj/kill-buffer-or-bury-alive "*external-open.log*") (helpful-key "p") (dwim-shell-command 1) (execute-extended-command nil "dwim-shell-command") (dwim-shell-commands-menu) (execute-extended-command nil "dwim-shell-commands-menu" "dwim-she") (execute-extended-command nil "dwim-shell-command" "dwim=") (find-file "~/code/dwim-shell-command/dwim-shell-commands.el" t) (helpful-key "\344") (execute-extended-command nil "dwim-shell-commands-menu") (helpful-key "a") (execute-extended-command nil "dwim-shell-commands-menu" "dwim=") (execute-extended-command nil "dwim-shell-command" "dwim-shell-comm") (helpful-key "\303") (time-zones) (execute-extended-command nil "time-zones" "timezon") (cj/kill-buffer-or-bury-alive "christine-2025-09-04-henry-jovel-construction-34550.pdf") (cj/kill-buffer-or-bury-alive "expenses-real-estate.org") (find-file "~/projects/jr-estate/event-candidates.org" t)))
(setq fontaine-preset-history '("default" "FiraCode-Literata" "Hack"))
-(setq string-rectangle-history '("-" " " " " " "))
+(setq string-rectangle-history '("0" "-" " " " " " "))
(setq org-read-date-history '(" " "15:00 " "12:00 "))
(setq read-char-history '("yes"))
(setq org-roam-node-history '("Biga #bread" "Louisiana Law On Recording Conversations" "assembly-ai-transcription"))
@@ -40,32 +40,96 @@
(setq chime-calendar-url \"https://calendar.google.com/calendar/u/0/r\")
(chime-mode 1)
(message \"Reloaded chime from ~/code/chime.el\"))" "chime-calendar-url"))
+(setq eww-prompt-history '("https://spacenews.com/pentagon-turns-to-government-owned-commercially-operated-satellites-amid-conflict-risks/"))
(setq org-refile-history '("Active Tasks" "Finances Open Work (todo.org)" "Inbox (inbox.org)" "Emacs Config Inbox (todo.org)" "Method 1: Make Using Emacs Frictionless [10/19]" "JR Estate Real Estate Ratowsky Event Log" "JR Estate Administration/Legal Event Log" "WTTRIN Resolved Tasks" "Finance Open Work (todo.org)" "Inbox" "Chime Open Work (todo.org)" "Chime Resolved Work"))
(setq read-number-history '("80"))
(setq magit-revision-history '("github/main" "origin/main"))
-(setq query-replace-history '("Craig" "Speaker A" "Claire" "Speaker B" "Justin Ratowsky" "Speaker C" "Craig Ratowsky" "Craig Jennings" "" "*" "Shane" "Christine" "Laura Smetanick" ", 2025" "## " "##" "**" "Rosalea" "Rosalie" "Laura" "Christine Ciarmello" "SOV" "sop" "Jonathan Shultis" "Jonathan Schultis"))
+(setq query-replace-history '("" #(" on Vimeo" 0 8 (dired-filename t) 8 9 (rear-nonsticky t dired-filename t)) ": " ": " "Claire: " "Craig:" "Craig Jennings" "Claire" "Craig" "Speaker A" "Speaker B" "Justin Ratowsky" "Speaker C" "Craig Ratowsky" "*" "Shane" "Christine" "Laura Smetanick" ", 2025" "## " "##" "**" "Rosalea" "Rosalie" "Laura"))
(setq org-tags-history '("quick" "laura" "bug" "enhancement" "doc" ":enhancement:enhancement" "drill"))
-(setq buffer-name-history '("The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt" "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log" "*emacs*" "*img-cache*" "*external-open.log*"
-;;; #<killed buffer>
- "christine-2025-09-04-henry-jovel-construction-34550.pdf" "expenses-real-estate.org" "kelly-pacific-dream-painting.vcf" "todo.org" "claire.vcf" "2025-11-21-10-07-39.txt" "Notes of The Truth About the World_ Basic Readings - James Rachels.pdf" "org-noter-workflow-spec.org" "early-init.el" "gcal.org" "2025-11-18-18-13-21-email-to-laura-hb-trip-planning.eml" "2025-11-13-13-30-plan-discussion-with-laura.txt" "2025-11-19-15-44-37.txt" "*scratch*" "*mu4e-last-update*" "todo.org<danneel>" "session-wrap-up.org" "NOTES.org" "inbox.org" "init.el" "weather-config.el" "*Messages*" "tests/testutil-events.el.~{index}~" "tests/test-chime-whitelist-blacklist-conflicts.elc.~{index}~" "schedule.org" "draft-email-to-mark-withdraw-offers.txt" "email-to-jonathan-draft.txt" "2025-11-17-16-17-43.txt" "email-to-jonathan-draft.txt<craig-draft-to-jonathan>" "email-to-jonathan-draft.txt<danneel>" "README.txt" "2025-11-17-12-47-15.txt" "todo.org<finances>" "attorney_questions_and_interview.org" "HealthInsuranceInfo.pdf" "garglk.ini" "Malyon Transcript" "archive.org" "webclipped.org" "todo.org<jr-estate>" "calendar-sync.el" "education.org" "zoxide.sh" "test-chime-tooltip-day-calculation.el"))
-(setq file-name-history '("~/code/dwim-shell-command/dwim-shell-commands.el" "/tmp/claude-prompt-2f3c0e6a-6bd2-4d0f-b0bf-450660b379a9.md" "~/projects/jr-estate/event-candidates.org" "/tmp/claude-prompt-66f67f73-3dcc-4317-bd46-afd6f723a60a.md" "/tmp/claude-prompt-7cf290fa-2406-4771-bed4-2eaddf354c07.md" "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" "/tmp/claude-prompt-0e67f38d-d20e-4542-815a-1f937fd962e3.md" "~/.emacs.d/docs/org-noter-workflow-spec.org" "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " "~/projects/jr-estate/docs/draft-email-to-laura-hb-trip.org" "~/sync/books/Georges Simenon/A Crime in Holland (2806)/A Crime in Holland - Georges Simenon.epub" "~/projects/clipper/docs/tenant-comparison-2025-11.org" "~/documents/dropbox/Carrollton Construction/craig-draft-to-jonathan" "~/projects/danneel/inbox/laura's flights to hb.txt" "~/projects/danneel/inbox/car rental.txt" "~/projects/danneel/inbox/" "~/projects/documents/inbox" "~/.config/garglk.ini" "~/sync/org/text.games/sherlock-r26-s880127.z5" "~/sync/org/text.games/sherlock.riddle.of.the.crown.jewels.1987.z5" "~/sync/org/text.games/nameless.2012.z8" "~/.profile" "~/runme.sh" "~/.emacs.d/modules/system-utils.el" "~/test.txt" "~/projects/jr-estate/inbox/text-conversation-justin-craig-re-laura's-arrival.txt" "~/projects/jr-estate/inbox/justin-craig-craig-3:39-pm.org" "~/videos/Global Finance Pulse-The Prof G - Deficits & Debt - Will They Crash the Economy?.webm" "~/videos/politics/" "~/code/org-drill/test/org-drill-test.el" "~/.emacs.d/.time-zones.el" "~/code/org-drill/todo.org" "~/projects/jr-estate/inbox/" "~rpc/" "~/projects/claude-templates" "/tmp/claude-prompt-bdd8c73a-233d-4598-ba97-59bf1238a772.md" "/tmp/claude-prompt-e8677ff5-14bf-4254-a529-6e471dd88347.md" "/tmp/claude-prompt-7940afe3-09f6-49e8-9793-20a616c04b5e.md" "/tmp/claude-prompt-f6799835-f2d0-4cfa-ab66-53f90407667b.md" "/tmp/claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.md" "~/projects/jr-estate/jr_info/secrets/original/" "~/projects/jr-estate/email-laura-closing-costs.txt" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txt" "/tmp/claude-prompt-7c79b988-8b14-420f-87b5-2f9a2c725c37.md" "~/code/archsetup/docs/archsetup-v2mom.org" "~/downloads/goldens-book-issues.org" "/tmp/claude-prompt-48fc618e-a826-43e0-aa0e-57b679845ded.md" "~/.emacs.d/docs/NOTES.org" "~/projects/danneel/inbox" "~/.authinfo.gpg"))
+(setq buffer-name-history '("gcal.org" "org-agenda-config.el" "calendar-sync.el" "The Prof G Pod – Scott Galloway-Money & Masculinity — Scott Galloway & Ed Elson on What Defines a Man | Prof G Markets.f399.mp4.part" "Malyon Transcript" "*eww*" "assets" "The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt" "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log" "*emacs*" "*img-cache*" "*external-open.log*" "christine-2025-09-04-henry-jovel-construction-34550.pdf" "expenses-real-estate.org" "kelly-pacific-dream-painting.vcf" "todo.org" "claire.vcf" "2025-11-21-10-07-39.txt" "Notes of The Truth About the World_ Basic Readings - James Rachels.pdf" "org-noter-workflow-spec.org" "early-init.el" "2025-11-18-18-13-21-email-to-laura-hb-trip-planning.eml" "2025-11-13-13-30-plan-discussion-with-laura.txt" "2025-11-19-15-44-37.txt" "*scratch*" "*mu4e-last-update*" "todo.org<danneel>" "session-wrap-up.org" "NOTES.org" "inbox.org" "init.el" "weather-config.el" "*Messages*" "tests/testutil-events.el.~{index}~" "tests/test-chime-whitelist-blacklist-conflicts.elc.~{index}~" "schedule.org" "draft-email-to-mark-withdraw-offers.txt" "email-to-jonathan-draft.txt" "2025-11-17-16-17-43.txt" "email-to-jonathan-draft.txt<craig-draft-to-jonathan>" "email-to-jonathan-draft.txt<danneel>" "README.txt" "2025-11-17-12-47-15.txt" "todo.org<finances>" "attorney_questions_and_interview.org" "HealthInsuranceInfo.pdf" "garglk.ini" "archive.org"))
+(setq file-name-history '("~/.emacs.d/modules/calendar-sync.el" "~/archive/magic/Daniel Madison System/" "~/archive/magic/Daniel Madison Induction" "~/archive/magic/Daniel Madison Expert" "~/projects/finances/inbox/Danneel-street-hoa-payment.eml" "~/sync/org/text.games/planetfall.1983.z3" "~/projects/jr-estate/assets" "~/projects/jr-estate/inbox/" "~/code/dwim-shell-command/dwim-shell-commands.el" "/tmp/claude-prompt-2f3c0e6a-6bd2-4d0f-b0bf-450660b379a9.md" "~/projects/jr-estate/event-candidates.org" "/tmp/claude-prompt-66f67f73-3dcc-4317-bd46-afd6f723a60a.md" "/tmp/claude-prompt-7cf290fa-2406-4771-bed4-2eaddf354c07.md" "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" "/tmp/claude-prompt-0e67f38d-d20e-4542-815a-1f937fd962e3.md" "~/.emacs.d/docs/org-noter-workflow-spec.org" "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " "~/projects/jr-estate/docs/draft-email-to-laura-hb-trip.org" "~/sync/books/Georges Simenon/A Crime in Holland (2806)/A Crime in Holland - Georges Simenon.epub" "~/projects/clipper/docs/tenant-comparison-2025-11.org" "~/documents/dropbox/Carrollton Construction/craig-draft-to-jonathan" "~/projects/danneel/inbox/laura's flights to hb.txt" "~/projects/danneel/inbox/car rental.txt" "~/projects/danneel/inbox/" "~/projects/documents/inbox" "~/.config/garglk.ini" "~/sync/org/text.games/sherlock-r26-s880127.z5" "~/sync/org/text.games/sherlock.riddle.of.the.crown.jewels.1987.z5" "~/sync/org/text.games/nameless.2012.z8" "~/.profile" "~/runme.sh" "~/.emacs.d/modules/system-utils.el" "~/test.txt" "~/projects/jr-estate/inbox/text-conversation-justin-craig-re-laura's-arrival.txt" "~/projects/jr-estate/inbox/justin-craig-craig-3:39-pm.org" "~/videos/Global Finance Pulse-The Prof G - Deficits & Debt - Will They Crash the Economy?.webm" "~/videos/politics/" "~/code/org-drill/test/org-drill-test.el" "~/.emacs.d/.time-zones.el" "~/code/org-drill/todo.org" "~rpc/" "~/projects/claude-templates" "/tmp/claude-prompt-bdd8c73a-233d-4598-ba97-59bf1238a772.md" "/tmp/claude-prompt-e8677ff5-14bf-4254-a529-6e471dd88347.md" "/tmp/claude-prompt-7940afe3-09f6-49e8-9793-20a616c04b5e.md" "/tmp/claude-prompt-f6799835-f2d0-4cfa-ab66-53f90407667b.md" "/tmp/claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.md" "~/projects/jr-estate/jr_info/secrets/original/" "~/projects/jr-estate/email-laura-closing-costs.txt" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txt"))
(setq mu4e--search-hist '("Laura Smetanick" "AJ" "wetmore" "mark"))
-(setq consult--line-history '("menu" "Rivera" "Speaker" "weeks" "ession history" "da" "weath" "MSY" "permit" "Ber" "alias cd" "Ros" "Rosa" "interaction with " "modelin" "mousetrap" "font" "org-dri" "base" "Lexe" "Charis" "Litera" "Literata" "Cha" "source Serif" "source serif" "Soufri" "Soufrier" "Greater" "trans" "Scott" "list" "bulle" "session" "Session" "start auto-sync" "judge" "Sorry Justin" "jas" "audio" "claude-temp" "active" "flych" "debug" "wrap" "line" "contractor" "org-agen"))
-(setq minibuffer-history '("64k" "128k" "~/projects/finances/" "modules/dwim-shell-config.el" "~/.emacs.d/" "dwim-shell-command.el" "~/code/dwim-shell-command/" "Huntington Beach, CA" "~/projects/jr-estate/" "~/projects/danneel/" "masterpdfeditor5" "todo.org" "Jabra SPEAK 510 USB" "inbox/claire.vcf" "Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "Comes out guns a-blazing on the first sentence. Pretty impressive opening statement. " "nature-and-spirit-an-essay-in-ecstatic-na-robert-s-corrington" "second note. socrates section. " "testing notes now" "the-truth-about-the-world-basic-readings-james-rachels" "nothing else to note here. " "I was going to read Aristotle's polics. But they started without me. " "Bloody? yick. " "...developing Nations, heh. " "The Truth About the World_ Basic Readings - James Rachels.pdf" "Is there any other kind of note? " "Preface Note" "Preface" "this is the socrates section. " "the-truth-about-the-world" "hey there. just testing org-noter. " "The Truth About the World" "The Truth About the World - James Rachels" "early-init.el" "factotum" "Wolf Hall - Hilary Mantel" "New Orleans, LA" "docs/NOTES.org" "ratowsky_real_estate/2025-11-13-13-30-plan-discussion-with-laura.txt" "evince" "evincce" "zathura" "masterpdf5" "docs/workflows/session-wrap-up.org" "~/projects/claude-templates/" "~/code/chime.el/" "The Yellow Dog - Georges Simenon" "David Bowie/Hunky Dory - 1971/" "and" "assets/2025-08-01-Meeting_Notes.pdf"))
-(setq consult--buffer-history '("*Extract audio*<3>øˆ€€‚" "*Messages*øˆ€€‚" "todo.org<jr-estate>øˆ€€‚" "*scratch*øˆ€€‚" "org-noter-workflow-spec.orgøˆ€€‚" "20240104102128-biga.orgøˆ€€‚" "*mu4e-last-update*øˆ€€‚" "todo.org<danneel>øˆ€€‚" "email-to-jonathan-draft.txtøˆ€€‚" "todo.org<finances>øˆ€€‚" "todo.orgøˆ€€‚" "Craig_Jennings_Health_Insurance_Card_2025_Back.jpgøˆ€€‚" "Craig_Jennings_Health_Insurance_Card_2025_Front.jpgøˆ€€‚" "Toyota_FJ_Cruiser_Certificate_of_Title.pdføˆ€€‚" "*Org Agenda*øˆ€€‚" "*wttr.in*øˆ€€‚" "reconcile-open-repos.eløˆ€€‚" "Essex Dogs - Dan Jones.epubøˆ€€‚" "Classical Mathematical Logic_ The Semantic - Richard L. Epstein.pdføˆ€€‚" "Ontology Made Easy - Amie Lynn Thomasson.pdføˆ€€‚" "*dashboard*øˆ€€‚" "~/.emacs.d/modules/system-utils.eløˆ€€ƒ" "test.txtøˆ€€‚" "inbox.orgøˆ€€‚" "*calibredb*øˆ€€‚" "text-conversation-justin-craig-re-laura's-arrival.txtøˆ€€‚" "magit: .emacs.døˆ€€‚" "MEETING-CHEAT-SHEET-NOV-4.orgøˆ€€‚" "*mu4e-main*øˆ€€‚" "*emacs:err*øˆ€€‚" "danneel-inbox-zero.orgøˆ€€‚" "NOTES.org<claude-templates>øˆ€€‚" "NOTES.org<danneel>øˆ€€‚" "2025-11-07.orgøˆ€€‚" "claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.mdøˆ€€‚" "\"Update 2025-11-07 Fri\"<2>øˆ€€‚" "dfdf-closing-costs" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txtøˆ€€ƒ" "SETTLEMENT-NUMBERS-NOV-7-CALL.orgøˆ€€‚" "MARK-CALL-CHEAT-SHEET-NOV-7.orgøˆ€€‚" "2025-11-05.orgøˆ€€‚" "October 2025 Invoice - Jennings.pdføˆ€€‚" "*Org ASCII Export*øˆ€€‚" "NOTES.orgøˆ€€‚" "jr-estateøˆ€€‚" "NOTES.org<jr-estate>øˆ€€‚" "NOTES.org<finances>øˆ€€‚" "NOTES-NEW.orgøˆ€€‚" "NOTES.org<finances/docs>øˆ€€‚" "NOTES.org<.emacs.d>øˆ€€‚"))
-(setq extended-command-history '("dwim-shell-command" "dwim-shell-commands-menu" "time-zones" "cj/org-sort-by-todo-and-priority" "bookmark-set" "package-upgrade-all" "cj/org-appear-toggle" "cj/reset-auth-cache" "align-regexp" "org-mode" "cj/org-clear-element-cache" "toggle-debug-on-error" "malyon" "org-gcal-reload-client-id-secret" "calendar" "projectile-switch-project" "cj/arrayify" "mouse-trap-mode" "describe-mode" "org-drill-resume" "org-drill" "chime-mode" "chime-check" "chime-validate-configuration" "org-drill-test-display" "projectile-discover-projects-in-search-path" "calculator" "calc" "mu4e-compose-mode" "wttrin-debug-show-log" "cj/build-org-agenda-list" "wttrin-mode-line-mode" "cj/flyspell-then-abbrev" "dired-unmark-all-marks" "emoji-search" "visual-line-mode" "cj/transcribe-audio" "cj/dired-copy-path-as-kill" "org-lint" "load-file" "wttrin" "wttrin-clear-cache" "debug-wttrin-show-raw" "chime--debug-dump-tooltip" "chime--debug-dump-events"))
+(setq consult--line-history '("gcal" "Lazy" "EIN" "menu" "Rivera" "Speaker" "weeks" "ession history" "da" "weath" "MSY" "permit" "Ber" "alias cd" "Ros" "Rosa" "interaction with " "modelin" "mousetrap" "font" "org-dri" "base" "Lexe" "Charis" "Litera" "Literata" "Cha" "source Serif" "source serif" "Soufri" "Soufrier" "Greater" "trans" "Scott" "list" "bulle" "session" "Session" "start auto-sync" "judge" "Sorry Justin" "jas" "audio" "claude-temp" "active" "flych" "debug" "wrap" "line" "contractor"))
+(setq minibuffer-history '("proton" "modules/user-constants.el" "~/.emacs.d/" "Wolf Hall - Hilary Mantel" "Roberto Gini/Fantasia-Suites John Jenkins and his ‘most esteemed friend’ William Lawes/" "Oberlin Consort of Viols/5 and 6 part Fantasies of William Lawes/" "Baroque Sonatas.m3u" "Venice Classic Radio.m3u" "Radio Caprice Classical Lute.m3u" "BAGeL Radio.m3u" "Love and Rockets" "Love and Rockets/Earth Sun Moon (1987)/06 Lazy.flac" "Love and Rockets/" "Jabra SPEAK 510 USB" "inbox/RejectionNotice_0_async.pdf" "~/projects/jr-estate/" "Huntington Beach, CA" "docs/NOTES.org" "~/projects/finances/" "[ADM] Addendum No. 1.pdf" "64k" "128k" "modules/dwim-shell-config.el" "dwim-shell-command.el" "~/code/dwim-shell-command/" "~/projects/danneel/" "masterpdfeditor5" "todo.org" "inbox/claire.vcf" "Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "Comes out guns a-blazing on the first sentence. Pretty impressive opening statement. " "nature-and-spirit-an-essay-in-ecstatic-na-robert-s-corrington" "second note. socrates section. " "testing notes now" "the-truth-about-the-world-basic-readings-james-rachels" "nothing else to note here. " "I was going to read Aristotle's polics. But they started without me. " "Bloody? yick. " "...developing Nations, heh. " "The Truth About the World_ Basic Readings - James Rachels.pdf" "Is there any other kind of note? " "Preface Note" "Preface" "this is the socrates section. " "the-truth-about-the-world" "hey there. just testing org-noter. " "The Truth About the World" "The Truth About the World - James Rachels" "early-init.el" "factotum"))
+(setq consult--buffer-history '("*scratch*øˆ€€‚" "user-constants.eløˆ€€‚" "~/.emacs.d/modules/calendar-sync.eløˆ€€ƒ" "*EMMS-Playlist*øˆ€€‚" "*Extract audio*<3>øˆ€€‚" "*Messages*øˆ€€‚" "todo.org<jr-estate>øˆ€€‚" "org-noter-workflow-spec.orgøˆ€€‚" "20240104102128-biga.orgøˆ€€‚" "*mu4e-last-update*øˆ€€‚" "todo.org<danneel>øˆ€€‚" "email-to-jonathan-draft.txtøˆ€€‚" "todo.org<finances>øˆ€€‚" "todo.orgøˆ€€‚" "Craig_Jennings_Health_Insurance_Card_2025_Back.jpgøˆ€€‚" "Craig_Jennings_Health_Insurance_Card_2025_Front.jpgøˆ€€‚" "Toyota_FJ_Cruiser_Certificate_of_Title.pdføˆ€€‚" "*Org Agenda*øˆ€€‚" "*wttr.in*øˆ€€‚" "reconcile-open-repos.eløˆ€€‚" "Essex Dogs - Dan Jones.epubøˆ€€‚" "Classical Mathematical Logic_ The Semantic - Richard L. Epstein.pdføˆ€€‚" "Ontology Made Easy - Amie Lynn Thomasson.pdføˆ€€‚" "*dashboard*øˆ€€‚" "~/.emacs.d/modules/system-utils.eløˆ€€ƒ" "test.txtøˆ€€‚" "inbox.orgøˆ€€‚" "*calibredb*øˆ€€‚" "text-conversation-justin-craig-re-laura's-arrival.txtøˆ€€‚" "magit: .emacs.døˆ€€‚" "MEETING-CHEAT-SHEET-NOV-4.orgøˆ€€‚" "*mu4e-main*øˆ€€‚" "*emacs:err*øˆ€€‚" "danneel-inbox-zero.orgøˆ€€‚" "NOTES.org<claude-templates>øˆ€€‚" "NOTES.org<danneel>øˆ€€‚" "2025-11-07.orgøˆ€€‚" "claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.mdøˆ€€‚" "\"Update 2025-11-07 Fri\"<2>øˆ€€‚" "dfdf-closing-costs" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txtøˆ€€ƒ" "SETTLEMENT-NUMBERS-NOV-7-CALL.orgøˆ€€‚" "MARK-CALL-CHEAT-SHEET-NOV-7.orgøˆ€€‚" "2025-11-05.orgøˆ€€‚" "October 2025 Invoice - Jennings.pdføˆ€€‚" "*Org ASCII Export*øˆ€€‚" "NOTES.orgøˆ€€‚" "jr-estateøˆ€€‚" "NOTES.org<jr-estate>øˆ€€‚" "NOTES.org<finances>øˆ€€‚"))
+(setq extended-command-history '("calendar-sync-status" "calendar-sync-now" "malyon-quit" "malyon" "dwim-shell-command" "dwim-shell-commands-menu" "time-zones" "cj/org-sort-by-todo-and-priority" "bookmark-set" "package-upgrade-all" "cj/org-appear-toggle" "cj/reset-auth-cache" "align-regexp" "org-mode" "cj/org-clear-element-cache" "toggle-debug-on-error" "org-gcal-reload-client-id-secret" "calendar" "projectile-switch-project" "cj/arrayify" "mouse-trap-mode" "describe-mode" "org-drill-resume" "org-drill" "chime-mode" "chime-check" "chime-validate-configuration" "org-drill-test-display" "projectile-discover-projects-in-search-path" "calculator" "calc" "mu4e-compose-mode" "wttrin-debug-show-log" "cj/build-org-agenda-list" "wttrin-mode-line-mode" "cj/flyspell-then-abbrev" "dired-unmark-all-marks" "emoji-search" "visual-line-mode" "cj/transcribe-audio" "cj/dired-copy-path-as-kill" "org-lint" "load-file" "wttrin" "wttrin-clear-cache" "debug-wttrin-show-raw" "chime--debug-dump-tooltip" "chime--debug-dump-events"))
(setq projectile-project-command-history '#s(hash-table test equal))
-(setq kill-ring '("128k" #(" Stream #0:1 -> #0:0 (copy)
-[ipod @ 0x563ae72357c0] Could not find tag for codec opus in stream #0, codec not currently supported in container
-[out#0/ipod @ 0x563ae72356c0] Could not write header (incorrect codec parameters ?): Invalid argument
-Conversion failed!
-" 0 265 (fontified t)) "cl--assertion-failed: Not a .mp4\\|mkv\\|webm\\|avi\\|mov\\|flv\\|wmv\\|m4v\\|mpg\\|mpeg\\|ogv\\|3gp\\|ts file" "/home/cjennings/projects/finances/The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.webm" #("cj/music-add-dired-selection is an interactive function defined in
-music-config.el.
-" 35 46 (button (t) category helpful-info-button-button info-node "(elisp)Using Interactive") 67 82 (button (t) category helpful-navigate-button-button path "/home/cjennings/.emacs.d/modules/music-config.el" position 16148)) #("TheTheTheTheTheThe" 0 3 (mouse-face highlight dired-filename t help-echo #1="mouse-2: visit this file in other window" fontified t) 3 6 (mouse-face highlight dired-filename t help-echo #1# fontified t) 6 9 (fontified t help-echo #1# dired-filename t mouse-face highlight) 9 12 (mouse-face highlight dired-filename t help-echo #1# fontified t) 12 15 (fontified t help-echo #1# dired-filename t mouse-face highlight) 15 18 (mouse-face highlight dired-filename t help-echo #1# fontified t)) #("TheTheTheTheTheTheTheThe" 0 3 (mouse-face highlight dired-filename t help-echo #2="mouse-2: visit this file in other window" fontified t) 3 6 (mouse-face highlight dired-filename t help-echo #2# fontified t) 6 9 (fontified t help-echo #2# dired-filename t mouse-face highlight) 9 12 (mouse-face highlight dired-filename t help-echo #2# fontified t) 12 15 (fontified t help-echo #2# dired-filename t mouse-face highlight) 15 18 (mouse-face highlight dired-filename t help-echo #2# fontified t) 18 21 (fontified t help-echo #2# dired-filename t mouse-face highlight) 21 24 (mouse-face highlight dired-filename t help-echo #2# fontified t)) #("TheTheTheTheTheTheTheTheThe" 0 3 (fontified t help-echo #3="mouse-2: visit this file in other window" dired-filename t mouse-face highlight) 3 6 (fontified t help-echo #3# dired-filename t mouse-face highlight) 6 9 (mouse-face highlight dired-filename t help-echo #3# fontified t) 9 12 (fontified t help-echo #3# dired-filename t mouse-face highlight) 12 15 (mouse-face highlight dired-filename t help-echo #3# fontified t) 15 18 (fontified t help-echo #3# dired-filename t mouse-face highlight) 18 21 (mouse-face highlight dired-filename t help-echo #3# fontified t) 21 24 (fontified t help-echo #3# dired-filename t mouse-face highlight) 24 27 (mouse-face highlight dired-filename t help-echo #3# fontified t))))
-(setq command-history '((cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt") (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log") (cj/kill-buffer-or-bury-alive "*emacs*") (cj/kill-buffer-or-bury-alive "*img-cache*") (cj/kill-buffer-or-bury-alive "*external-open.log*") (helpful-key "p") (dwim-shell-command 1) (execute-extended-command nil "dwim-shell-command") (dwim-shell-commands-menu) (execute-extended-command nil "dwim-shell-commands-menu" "dwim-she") (execute-extended-command nil "dwim-shell-command" "dwim=") (find-file "~/code/dwim-shell-command/dwim-shell-commands.el" t) (helpful-key "\344") (execute-extended-command nil "dwim-shell-commands-menu") (helpful-key "a") (execute-extended-command nil "dwim-shell-commands-menu" "dwim=") (execute-extended-command nil "dwim-shell-command" "dwim-shell-comm") (helpful-key "\303") (wttrin "Huntington Beach, CA") (time-zones) (execute-extended-command nil "time-zones" "timezon") (cj/kill-buffer-or-bury-alive "christine-2025-09-04-henry-jovel-construction-34550.pdf") (cj/kill-buffer-or-bury-alive "expenses-real-estate.org") (find-file "~/projects/jr-estate/event-candidates.org" t) (cj/org-sort-by-todo-and-priority) (execute-extended-command nil "cj/org-sort-by-todo-and-priority") (cj/kill-buffer-or-bury-alive "kelly-pacific-dream-painting.vcf") (find-file "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" t) (cj/kill-buffer-or-bury-alive "todo.org") (cj/kill-buffer-or-bury-alive "claire.vcf") (cj/kill-buffer-or-bury-alive "2025-11-21-10-07-39.txt") (cj/open-file-with-command "masterpdfeditor5") (query-replace "Speaker A" "Craig" nil #1=(use-region-beginning) #2=(use-region-end) nil #3=(use-region-noncontiguous-p)) (query-replace "Speaker B" "Claire" nil #1# #2# nil #3#) (cj/kill-buffer-or-bury-alive "Notes of The Truth About the World_ Basic Readings - James Rachels.pdf") (pdf-view-position-to-register 113) (bookmark-set nil nil) (execute-extended-command nil "bookmark-set" "book") (cj/kill-buffer-or-bury-alive "org-noter-workflow-spec.org") (find-file "~/.emacs.d/docs/org-noter-workflow-spec.org" t) (cj/kill-buffer-or-bury-alive "early-init.el") (package-upgrade-all t) (execute-extended-command nil "package-upgrade-all" "package-upgra") (cj/kill-buffer-or-bury-alive "gcal.org") (wttrin "New Orleans, LA") (find-file "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " t) (query-replace "Speaker C" "Justin Ratowsky" nil #4=(use-region-beginning) #5=(use-region-end) nil #6=(use-region-noncontiguous-p)) (query-replace "Speaker A" "Craig Ratowsky" nil #4# #5# nil #6#) (query-replace "Speaker B" "Craig Jennings" nil #4# #5# nil #6#) (cj/kill-buffer-or-bury-alive "2025-11-18-18-13-21-email-to-laura-hb-trip-planning.eml")))
+(setq kill-ring '("1. Default of 2 calendars - do you want me to pre-populate the config with placeholder entries, or leave it empty by default?
+Leave it empty by default. However, this makes me ask: how are the calendar URLs stored? I see where we define \"gcal-file\" to be the destination to sync the google calendar contents to. We should also add a \"pcal-file\" to sync the proton calendar to. However, I don't see where the URL is defined. Can you tell me?
+
+2. Should calendar-sync-now have interactive calendar selection (completing-read), or always sync all?
+If this is easy to implement, that would be a big win for the user experience.
+
+3. Any preference on status display format (message, buffer, or both)?
+I would like the messages to be displayed in the echo area and the appropriate buffer. " #("I would use message to put this both in the echo area and also " 0 63 (fontified t)) #("add a message" 0 4 (fontified t) 4 6 (fontified t) 6 13 (fontified t)) #("coming from. " 0 7 (fontified t) 7 13 (fontified t)) #("don't know" 0 6 (fontified t) 6 10 (fontified t)) #("for" 0 3 (fontified t)) #("may need" 0 4 (fontified t) 4 8 (fontified t)) #("for " 0 4 (fontified t)) #("we have the " 0 3 (fontified t) 3 8 (fontified t) 8 12 (fontified t)) #("However, since this is still my config, I definitely want you to use the existing varibles. These are defined here file:///home/cjennings/.emacs.d/modules/user-constants.el. The current config just syncs \"gcal-file\". The proton URL https://calendar.proton.me/api/calendar/v1/url/MpLtuwsUNoygyA_60GvJE5cz0hbREbrAPBEJoWDRpFEstnmzmEMDb7sjLzkY8kbkF10A7Be3wGKB1-vqaLf-pw==/calendar.ics?CacheKey=LrB9NG5Vfqp5p2sy90H13g%3D%3D&PassphraseKey=sURqFfACPM21d6AXSeaEXYCruimvSb8t0ce1vuxRAXk%3D should be " 0 115 (fontified t) 115 171 (font-lock-multiline t keymap #1=(keymap (follow-link . mouse-face) (mouse-3 . org-find-file-at-mouse) (mouse-2 . org-open-at-mouse)) mouse-face highlight face org-link htmlize-link #2=(:uri "file:///home/cjennings/.emacs.d/modules/user-constants.el") help-echo #3="LINK: file:///home/cjennings/.emacs.d/modules/user-constants.el" fontified t) 171 172 (font-lock-multiline t keymap #1# mouse-face highlight face org-link htmlize-link #2# help-echo #3# rear-nonsticky #6=(mouse-face highlight keymap invisible intangible help-echo org-linked-text htmlize-link) fontified t) 172 233 (fontified t) 233 479 (font-lock-multiline t keymap #1# mouse-face highlight face org-link htmlize-link #4=(:uri "https://calendar.proton.me/api/calendar/v1/url/MpLtuwsUNoygyA_60GvJE5cz0hbREbrAPBEJoWDRpFEstnmzmEMDb7sjLzkY8kbkF10A7Be3wGKB1-vqaLf-pw==/calendar.ics?CacheKey=LrB9NG5Vfqp5p2sy90H13g%3D%3D&PassphraseKey=sURqFfACPM21d6AXSeaEXYCruimvSb8t0ce1vuxRAXk%3D") help-echo #5="LINK: https://calendar.proton.me/api/calendar/v1/url/MpLtuwsUNoygyA_60GvJE5cz0hbREbrAPBEJoWDRpFEstnmzmEMDb7sjLzkY8kbkF10A7Be3wGKB1-vqaLf-pw==/calendar.ics?CacheKey=LrB9NG5Vfqp5p2sy90H13g%3D%3D&PassphraseKey=sURqFfACPM21d6AXSeaEXYCruimvSb8t0ce1vuxRAXk%3D" fontified t) 479 480 (font-lock-multiline t keymap #1# mouse-face highlight face org-link htmlize-link #4# help-echo #5# rear-nonsticky #6# fontified t) 480 491 (fontified t)) "gcal" #("the " 0 4 (fontified t)) #("should " 0 7 (fontified t)) "https://calendar.proton.me/api/calendar/v1/url/MpLtuwsUNoygyA_60GvJE5cz0hbREbrAPBEJoWDRpFEstnmzmEMDb7sjLzkY8kbkF10A7Be3wGKB1-vqaLf-pw==/calendar.ics?CacheKey=LrB9NG5Vfqp5p2sy90H13g%3D%3D&PassphraseKey=sURqFfACPM21d6AXSeaEXYCruimvSb8t0ce1vuxRAXk%3D" #("in modules/" 0 1 (font-lock-multiline t htmlize-link #7=(:uri "file:///home/cjennings/.emacs.d/modules/user-constants.elin") help-echo #8="LINK: file:///home/cjennings/.emacs.d/modules/user-constants.elin" mouse-face highlight face org-link fontified t) 1 2 (font-lock-multiline t htmlize-link #7# help-echo #8# mouse-face highlight face org-link rear-nonsticky #6# fontified t) 2 11 (fontified t)) "file:///home/cjennings/.emacs.d/modules/user-constants.el" #("gcal" 0 4 (fontified t)) #("Let's add placeholder entries.
+" 0 31 (fontified t) 31 32 (fontified t)) "1. Default of 2 calendars - do you want me to pre-populate the config with placeholder entries, or leave it empty by default?
+ 2. Should calendar-sync-now have interactive calendar selection (completing-read), or always sync all?
+ 3. Any preference on status display format (message, buffer, or both)?
+" #(" on Vimeo" 0 9 (fontified t help-echo #9="mouse-2: visit this file in other window" dired-filename t mouse-face highlight)) "P&dKYF$Yr8VXpk" #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #(" on Vimeo" 0 9 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("module11v1 on Vimeo" 0 19 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("EXPERT - MODULE 09 " 0 19 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #("TWO" 0 3 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("SIX" 0 3 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("SEVEN" 0 5 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("ONE" 0 3 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #("NINE" 0 4 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("FOUR" 0 4 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("EIGHT on Vimeo" 0 6 (mouse-face highlight dired-filename t help-echo #9# fontified t) 6 9 (fontified t help-echo #9# dired-filename t mouse-face highlight) 9 14 (fontified t help-echo #9# dired-filename t mouse-face highlight)) #("Vimeo-01" 0 6 (mouse-face highlight dired-filename t help-echo #9# fontified t) 6 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #("on Vimeo" 0 3 (mouse-face highlight dired-filename t help-echo #9# fontified t) 3 8 (mouse-face highlight dired-filename t help-echo #9# fontified t)) #(" on Vimeo" 0 9 (fontified t help-echo #9# dired-filename t mouse-face highlight)) "
+" "
+" "https://spacenews.com/pentagon-turns-to-government-owned-commercially-operated-satellites-amid-conflict-risks/" #("https://ais-sa3.cdnstream1.com/2606_128.mp3
+" 0 43 (emms-track (*track* (type . url) (name . "https://ais-sa3.cdnstream1.com/2606_128.mp3") (last-played 26922 1205 24934 569000) (play-count . 1)) face emms-playlist-track-face)) #("Love and Rockets - David J Haskins - My Dark Twin - California (Have a Nice Apocalypse!)
+" 0 88 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/My Dark Twin (2023)/CD2/02 California (Have a Nice Apocalypse!).flac") (info-composer . "David J Haskins") (info-date . "2023-06-09") (info-discnumber . "2") (info-tracknumber . "2") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "My Dark Twin") (info-title . "California (Have a Nice Apocalypse!)") (info-playing-time . 293) (info-mtime 26396 34868 920956 976000) (last-played 26922 549 275377 682000) (play-count . 1)) face emms-playlist-track-face)) #("Love and Rockets - Kevin Haskins - My Dark Twin - Sweet Lover Hangover (Remix)
+" 0 78 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/My Dark Twin (2023)/CD2/08 Sweet Lover Hangover (Remix).flac") (info-composer . "Kevin Haskins") (info-date . "2023-06-09") (info-discnumber . "2") (info-tracknumber . "8") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "My Dark Twin") (info-title . "Sweet Lover Hangover (Remix)") (info-playing-time . 243) (info-mtime 26396 34925 568955 204000) (last-played 26922 538 504011 729000) (play-count . 1)) face emms-playlist-track-face)) #("Love and Rockets - Kevin Haskins - Seventh Dream of Teenage Heaven - A Private Future
+Love and Rockets - Kevin Haskins - Seventh Dream of Teenage Heaven - The Dog-end of a Day Gone By
+" 0 85 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Seventh Dream of Teenage Heaven (1985)/02 A Private Future.flac") (info-composer . "Kevin Haskins") (info-date . "1985-01-01") (info-discnumber . "1") (info-tracknumber . "2") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Seventh Dream of Teenage Heaven") (info-title . "A Private Future") (info-playing-time . 306) (info-mtime 26396 28427 977847 367000))) 86 183 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Seventh Dream of Teenage Heaven (1985)/03 The Dog-end of a Day Gone By.flac") (info-composer . "Kevin Haskins") (info-date . "1985-01-01") (info-discnumber . "1") (info-tracknumber . "3") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Seventh Dream of Teenage Heaven") (info-title . "The Dog-end of a Day Gone By") (info-playing-time . 456) (info-mtime 26396 28447 689846 750000)))) #("Love and Rockets - Sorted!: The Best of Love and Rockets - The Dog-End of a Day Gone By
+Love and Rockets - Sorted!: The Best of Love and Rockets - Mirror People '88 [Single Version]
+Love and Rockets - Sorted!: The Best of Love and Rockets - Ball of Confusion (That's What the World Is Today)
+Love and Rockets - Sorted!: The Best of Love and Rockets - Yin and Yang (The Flowerpot Man)
+" 0 87 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Sorted!- The Best of Love and Rockets - 2003/02 The Dog-End of a Day Gone By.mp3") (info-genre . #10="Rock") (info-tracknumber . "02/15") (info-year . "2003") (info-album . "Sorted!: The Best of Love and Rockets") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "The Dog-End of a Day Gone By") (info-playing-time . 456) (info-mtime 26693 1750 898479 16000) (last-played 26922 103 739651 470000) (play-count . 2))) 88 181 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Sorted!- The Best of Love and Rockets - 2003/03 Mirror People '88 [Single Version].mp3") (info-genre . #10#) (info-tracknumber . "03/15") (info-year . "2003") (info-album . "Sorted!: The Best of Love and Rockets") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Mirror People '88 [Single Version]") (info-playing-time . 238) (info-mtime 26693 1750 982477 228000) (last-played 26922 107 540756 720000) (play-count . 1))) 182 291 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Sorted!- The Best of Love and Rockets - 2003/04 Ball of Confusion (That's What the World Is Today).mp3") (info-genre . #10#) (info-tracknumber . "04/15") (info-year . "2003") (info-album . "Sorted!: The Best of Love and Rockets") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Ball of Confusion (That's What the World Is Today)") (info-playing-time . 212) (info-mtime 26693 1751 47475 844000) (last-played 26922 105 474783 212000) (play-count . 1)) face emms-playlist-track-face) 292 383 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Sorted!- The Best of Love and Rockets - 2003/05 Yin and Yang (The Flowerpot Man).mp3") (info-genre . #10#) (info-tracknumber . "05/15") (info-year . "2003") (info-album . "Sorted!: The Best of Love and Rockets") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Yin and Yang (The Flowerpot Man)") (info-playing-time . 258) (info-mtime 26693 1751 118474 333000) (last-played 26922 109 593081 27000) (play-count . 2)))) #("Love and Rockets - Daniel Ash - Love And Rockets - Bound for Hell
+Love and Rockets - Lift - Lift
+Love and Rockets - Lift - Party's Not Over
+Love and Rockets - Lift - Deep Deep Down
+Love and Rockets - Lift - My Drug
+Love and Rockets - Lift - Resurrection Hex
+Love and Rockets - Lift - Bad For You
+Love and Rockets - Lift - Ghosts of the Multiple Feature
+Love and Rockets - Lift - Delicious Ocean
+Love and Rockets - Lift - Pink Flamingo
+Love and Rockets - Lift - Too Much Choice
+Love and Rockets - Lift - Holy Fool
+Love and Rockets - Lift - R.I.P. 20 C.
+Love and Rockets - Lift - Lift (Malibu mix)
+Love and Rockets - David J - Hot Trip to Heaven - Set Me Free
+Love and Rockets - David J - Hot Trip to Heaven - Be The Revolution
+Love and Rockets - David J - Hot Trip to Heaven - Voodoo Baby
+Love and Rockets - David J - Hot Trip to Heaven - Eclipse
+Love and Rockets - David J - Hot Trip to Heaven - Hot Trip To Heaven
+Love and Rockets - David J - Hot Trip to Heaven - No Worries
+Love and Rockets - David J - Hot Trip to Heaven - This Heaven
+Love and Rockets - David J - Hot Trip to Heaven - Trip & Glide
+Love and Rockets - David J - Hot Trip to Heaven - Ugly
+Love and Rockets - David J Haskins - Hot Trip to Heaven - Body and Soul (Parts 1 & 2)
+Love and Rockets - Daniel Ash - Express - B-side No. 2
+Love and Rockets - Daniel Ash - Express - B-side No. 1
+Love and Rockets - David J Haskins - Love And Rockets - So Alive
+Love and Rockets - David J Haskins - Assorted! - Bad Monkey
+Love and Rockets - David J Haskins - Assorted! - 1000 Watts of Your Love
+Love and Rockets - Daniel Ash - Assorted! - The Early Worm
+Love and Rockets - David J Haskins - Assorted! - Cuckoo Land
+Love and Rockets - Daniel Ash - Love And Rockets - The Teardrop Collector
+Love and Rockets - Seventh Dream of Teenage Heaven (2000 Remaster) - Saudade
+Love and Rockets - David J Haskins - Love And Rockets - Motorcycle
+Love and Rockets - David J Haskins - Love And Rockets - I Feel Speed
+Love and Rockets - David J Haskins - Earth Sun Moon - Lazy
+Love and Rockets - Daniel Ash - Earth Sun Moon - Everybody Wants To Go To Heaven
+" 0 65 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/06 Bound for Hell.flac") (info-composer . "Daniel Ash") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "6") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "Bound for Hell") (info-playing-time . 362) (info-mtime 26396 34613 919964 952000)) face emms-playlist-track-face) 66 96 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/13 Lift.mp3") (info-genre . #10#) (info-tracknumber . "13/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Lift") (info-playing-time . 244) (info-mtime 26693 1751 649463 31000)) face emms-playlist-track-face) 97 139 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/12 Party's Not Over.mp3") (info-genre . #10#) (info-tracknumber . "12/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Party's Not Over") (info-playing-time . 318) (info-mtime 26693 1751 582464 457000))) 140 180 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/11 Deep Deep Down.mp3") (info-genre . #10#) (info-tracknumber . "11/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Deep Deep Down") (info-playing-time . 561) (info-mtime 26693 1751 511465 968000)) face emms-playlist-track-face) 181 214 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/10 My Drug.mp3") (info-genre . #10#) (info-tracknumber . "10/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "My Drug") (info-playing-time . 523) (info-mtime 26693 1751 435467 586000))) 215 257 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/09 Resurrection Hex.mp3") (info-genre . #10#) (info-tracknumber . "09/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Resurrection Hex") (info-playing-time . 381) (info-mtime 26693 1751 368469 12000)) face emms-playlist-track-face) 258 295 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/08 Bad For You.mp3") (info-genre . #10#) (info-tracknumber . "08/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Bad For You") (info-playing-time . 234) (info-mtime 26693 1751 293470 608000))) 296 352 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/07 Ghosts of the Multiple Feature.mp3") (info-genre . #10#) (info-tracknumber . "07/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Ghosts of the Multiple Feature") (info-playing-time . 284) (info-mtime 26693 1751 229471 970000)) face emms-playlist-track-face) 353 394 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/06 Delicious Ocean.mp3") (info-genre . #10#) (info-tracknumber . "06/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Delicious Ocean") (info-playing-time . 246) (info-mtime 26693 1751 136473 950000))) 395 434 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/05 Pink Flamingo.mp3") (info-genre . #10#) (info-tracknumber . "05/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Pink Flamingo") (info-playing-time . 233) (info-mtime 26693 1751 66475 440000)) face emms-playlist-track-face) 435 476 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/04 Too Much Choice.mp3") (info-genre . #10#) (info-tracknumber . "04/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Too Much Choice") (info-playing-time . 290) (info-mtime 26693 1751 1476 823000))) 477 512 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/03 Holy Fool.mp3") (info-genre . #10#) (info-tracknumber . "03/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Holy Fool") (info-playing-time . 202) (info-mtime 26693 1750 923478 483000)) face emms-playlist-track-face) 513 551 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/02 R.I.P. 20 C..mp3") (info-genre . #10#) (info-tracknumber . "02/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "R.I.P. 20 C.") (info-playing-time . 400) (info-mtime 26693 1750 836480 335000))) 552 595 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Lift - 1998/01 Lift (Malibu mix).mp3") (info-genre . #10#) (info-tracknumber . "01/13") (info-year . "1998") (info-album . "Lift") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Lift (Malibu mix)") (info-playing-time . 256) (info-mtime 26693 1750 722482 761000)) face emms-playlist-track-face) 596 657 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/10 Set Me Free.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "10") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Set Me Free") (info-playing-time . 164) (info-mtime 26396 34455 257969 915000))) 658 725 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/09 Be The Revolution.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "9") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Be The Revolution") (info-playing-time . 404) (info-mtime 26396 34457 245969 853000)) face emms-playlist-track-face) 726 787 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/08 Voodoo Baby.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "8") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Voodoo Baby") (info-playing-time . 205) (info-mtime 26396 34446 791970 180000))) 788 845 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/07 Eclipse.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "7") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Eclipse") (info-playing-time . 138) (info-mtime 26396 34443 349970 288000)) face emms-playlist-track-face) 846 914 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/06 Hot Trip To Heaven.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "6") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Hot Trip To Heaven") (info-playing-time . 455) (info-mtime 26396 34453 512969 970000))) 915 975 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/05 No Worries.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "5") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "No Worries") (info-playing-time . 434) (info-mtime 26396 34424 96970 890000)) face emms-playlist-track-face) 976 1037 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/04 This Heaven.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "4") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "This Heaven") (info-playing-time . 428) (info-mtime 26396 34423 807970 899000))) 1038 1100 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/03 Trip & Glide.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "3") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Trip & Glide") (info-playing-time . 321) (info-mtime 26396 34418 562971 63000)) face emms-playlist-track-face) 1101 1155 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/02 Ugly.flac") (info-composer . "David J") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "2") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Ugly") (info-playing-time . 446) (info-mtime 26396 34431 858970 647000))) 1156 1241 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Hot Trip to Heaven (1994)/01 Body and Soul (Parts 1 & 2).flac") (info-composer . "David J Haskins") (info-date . "1994-09-27") (info-discnumber . "1") (info-tracknumber . "1") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Hot Trip to Heaven") (info-title . "Body and Soul (Parts 1 & 2)") (info-playing-time . 857) (info-mtime 26396 34440 45970 391000)) face emms-playlist-track-face) 1242 1296 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/13 B-side No. 2.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "13") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "B-side No. 2") (info-playing-time . 91) (info-mtime 26396 29020 739828 825000))) 1297 1351 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/12 B-side No. 1.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "12") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "B-side No. 1") (info-playing-time . 76) (info-mtime 26396 28920 39831 975000)) face emms-playlist-track-face) 1352 1416 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/08 So Alive.flac") (info-composer . "David J Haskins") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "8") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "So Alive") (info-playing-time . 257) (info-mtime 26396 34611 415965 31000) (last-played 26921 65274 970890 379000) (play-count . 1))) 1417 1476 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Assorted! (2013)/06 Bad Monkey.flac") (info-composer . "David J Haskins") (info-date . "2013-05-13") (info-discnumber . "1") (info-tracknumber . "6") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Assorted!") (info-title . "Bad Monkey") (info-playing-time . 260) (info-mtime 26396 34701 14962 228000) (last-played 26921 65253 56054 57000) (play-count . 1)) face emms-playlist-track-face) 1477 1549 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Assorted! (2013)/05 1000 Watts of Your Love.flac") (info-composer . "David J Haskins") (info-date . "2013-05-13") (info-discnumber . "1") (info-tracknumber . "5") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Assorted!") (info-title . "1000 Watts of Your Love") (info-playing-time . 168) (info-mtime 26396 34672 266963 127000) (last-played 26921 65260 944753 863000) (play-count . 1))) 1550 1608 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Assorted! (2013)/04 The Early Worm.flac") (info-composer . "Daniel Ash") (info-date . "2013-05-13") (info-discnumber . "1") (info-tracknumber . "4") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Assorted!") (info-title . "The Early Worm") (info-playing-time . 133) (info-mtime 26396 34673 499963 88000)) face emms-playlist-track-face) 1609 1669 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Assorted! (2013)/03 Cuckoo Land.flac") (info-composer . "David J Haskins") (info-date . "2013-05-13") (info-discnumber . "1") (info-tracknumber . "3") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Assorted!") (info-title . "Cuckoo Land") (info-playing-time . 168) (info-mtime 26396 34675 656963 21000))) 1670 1743 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/07 The Teardrop Collector.flac") (info-composer . "Daniel Ash") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "7") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "The Teardrop Collector") (info-playing-time . 249) (info-mtime 26396 34612 27965 11000)) face emms-playlist-track-face) 1744 1820 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Seventh Dream of Teenage Heaven (2000 Remaster) - 1985/07 Saudade.mp3") (info-genre . #10#) (info-tracknumber . "07/13") (info-year . "1985") (info-album . "Seventh Dream of Teenage Heaven (2000 Remaster)") (info-albumartist . "Love and Rockets") (info-artist . "Love and Rockets") (info-title . "Saudade") (info-playing-time . 300) (info-mtime 26693 1751 259471 332000) (last-played 26922 16 427071 153000) (play-count . 1))) 1821 1887 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/04 Motorcycle.flac") (info-composer . "David J Haskins") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "4") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "Motorcycle") (info-playing-time . 211) (info-mtime 26396 34585 678965 836000) (last-played 26921 65114 502112 999000) (play-count . 1)) face emms-playlist-track-face) 1888 1956 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/05 I Feel Speed.flac") (info-composer . "David J Haskins") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "5") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "I Feel Speed") (info-playing-time . 203) (info-mtime 26396 34586 628965 806000) (last-played 26921 65116 873934 411000) (play-count . 1))) 1957 2015 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Earth Sun Moon (1987)/06 Lazy.flac") (info-composer . "David J Haskins") (info-date . "1987-01-01") (info-discnumber . "1") (info-tracknumber . "6") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Earth Sun Moon") (info-title . "Lazy") (info-playing-time . 192) (info-mtime 26396 34337 196973 608000) (last-played 26921 65007 901513 623000) (play-count . 1)) face emms-playlist-track-face) 2016 2096 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Earth Sun Moon (1987)/10 Everybody Wants To Go To Heaven.flac") (info-composer . "Daniel Ash") (info-date . "1987-01-01") (info-discnumber . "1") (info-tracknumber . "10") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Earth Sun Moon") (info-title . "Everybody Wants To Go To Heaven") (info-playing-time . 313) (info-mtime 26396 34349 570973 221000) (last-played 26921 65043 640823 157000) (play-count . 1)))) #("Love and Rockets - Daniel Ash - Love And Rockets - **** (Jungle Law)
+Love and Rockets - Daniel Ash - Love And Rockets - No Big Deal
+Love and Rockets - Daniel Ash - Love And Rockets - The Purest Blue
+" 0 68 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/01 ---- (Jungle Law).flac") (info-composer . "Daniel Ash") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "1") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "**** (Jungle Law)") (info-playing-time . 274) (info-mtime 26396 34587 967965 764000)) face emms-playlist-track-face) 69 131 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/02 No Big Deal.flac") (info-composer . "Daniel Ash") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "2") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "No Big Deal") (info-playing-time . 296) (info-mtime 26396 34586 931965 796000)) face emms-playlist-track-face) 132 198 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Love And Rockets (2002)/03 The Purest Blue.flac") (info-composer . "Daniel Ash") (info-date . "2002-09-02") (info-discnumber . "1") (info-tracknumber . "3") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Love And Rockets") (info-title . "The Purest Blue") (info-playing-time . 223) (info-mtime 26396 34584 145965 884000) (last-played 26921 65093 568492 580000) (play-count . 1)))) #("Love and Rockets - Daniel Ash - Express - It Could Be Sunshine
+Love and Rockets - Daniel Ash - Express - Kundalini Express
+Love and Rockets - Daniel Ash - Express - All in My Mind
+Love and Rockets - Daniel Ash - Express - Life In Laralay
+Love and Rockets - Daniel Ash - Express - Yin and Yang (The Flowerpot Man)
+Love and Rockets - Daniel Ash - Express - Love Me
+Love and Rockets - Daniel Ash - Express - All in My Mind (Acoustic Version)
+Love and Rockets - Daniel Ash - Express - An American Dream
+Love and Rockets - Daniel Ash - Express - Angels and Devils
+" 0 62 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/01 It Could Be Sunshine.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "1") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "It Could Be Sunshine") (info-playing-time . 298) (info-mtime 26396 28788 832836 79000) (last-played 26921 65198 564062 590000) (play-count . 1)) face emms-playlist-track-face) 63 122 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/02 Kundalini Express.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "2") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "Kundalini Express") (info-playing-time . 348) (info-mtime 26396 34284 388975 260000)) face emms-playlist-track-face) 123 179 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/03 All in My Mind.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "3") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "All in My Mind") (info-playing-time . 283) (info-mtime 26396 34280 248975 390000))) 180 237 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/04 Life In Laralay.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "4") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "Life In Laralay") (info-playing-time . 212) (info-mtime 26396 28776 248836 473000)) face emms-playlist-track-face) 238 312 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/05 Yin and Yang (The Flowerpot Man).flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "5") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "Yin and Yang (The Flowerpot Man)") (info-playing-time . 356) (info-mtime 26396 28792 650835 960000))) 313 362 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/06 Love Me.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "6") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "Love Me") (info-playing-time . 234) (info-mtime 26396 28893 188832 815000)) face emms-playlist-track-face) 363 438 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/07 All in My Mind (Acoustic Version).flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "7") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "All in My Mind (Acoustic Version)") (info-playing-time . 304) (info-mtime 26396 28893 933832 792000) (last-played 26922 455 613977 560000) (play-count . 1))) 439 498 (emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/08 An American Dream.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "8") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "An American Dream") (info-playing-time . 369) (info-mtime 26396 28921 78831 942000)) face emms-playlist-track-face) 499 558 (face emms-playlist-track-face emms-track (*track* (type . file) (name . "/home/cjennings/music/Love and Rockets/Express (1986)/09 Angels and Devils.flac") (info-composer . "Daniel Ash") (info-date . "1986-09-15") (info-discnumber . "1") (info-tracknumber . "9") (info-artist . "Love and Rockets") (info-albumartist . "Love and Rockets") (info-album . "Express") (info-title . "Angels and Devils") (info-playing-time . 370) (info-mtime 26396 28919 535831 991000))))))
+(setq command-history '((calendar-sync-status) (execute-extended-command nil "calendar-sync-status" "calendar-sync") (cj/kill-buffer-or-bury-alive "gcal.org") (calendar-sync-now "proton") (execute-extended-command nil "calendar-sync-now" "calendar-sync") (cj/kill-buffer-or-bury-alive "org-agenda-config.el") (cj/kill-buffer-or-bury-alive "calendar-sync.el") (dired-create-directory "~/archive/magic/Daniel Madison System/") (query-replace #(" on Vimeo" 0 8 (dired-filename t) 8 9 (rear-nonsticky t dired-filename t)) "" nil (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (string-rectangle 201 892 "0") (dired-create-directory "~/archive/magic/Daniel Madison Induction") (dired-create-directory "~/archive/magic/Daniel Madison Expert") (write-file "~/projects/finances/inbox/Danneel-street-hoa-payment.eml" t) (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-Money & Masculinity — Scott Galloway & Ed Elson on What Defines a Man | Prof G Markets.f399.mp4.part") (cj/kill-buffer-or-bury-alive "Malyon Transcript") (malyon-quit) (execute-extended-command nil "malyon-quit" "malyon") (malyon "~/sync/org/text.games/planetfall.1983.z3") (execute-extended-command nil "malyon" "maly") (cj/kill-buffer-or-bury-alive "*eww*") (eww "https://spacenews.com/pentagon-turns-to-government-owned-commercially-operated-satellites-amid-conflict-risks/" nil) (wttrin "Huntington Beach, CA") (query-replace ": " ": " nil #1=(use-region-beginning) #2=(use-region-end) nil #3=(use-region-noncontiguous-p)) (query-replace "Craig:" "Claire: " nil #1# #2# nil #3#) (query-replace "Claire" "Craig Jennings" nil #1# #2# nil #3#) (cj/kill-buffer-or-bury-alive "assets") (find-file "~/projects/jr-estate/assets" t) (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-China's Renewable Energy Dominance in the AI Race | China Decode.txt") (cj/kill-buffer-or-bury-alive "The Prof G Pod – Scott Galloway-The Whole Market Looks Expensive — Is it Time to De-Risk? | Prof G Markets.log") (cj/kill-buffer-or-bury-alive "*emacs*") (cj/kill-buffer-or-bury-alive "*img-cache*") (cj/kill-buffer-or-bury-alive "*external-open.log*") (helpful-key "p") (dwim-shell-command 1) (execute-extended-command nil "dwim-shell-command") (dwim-shell-commands-menu) (execute-extended-command nil "dwim-shell-commands-menu" "dwim-she") (execute-extended-command nil "dwim-shell-command" "dwim=") (find-file "~/code/dwim-shell-command/dwim-shell-commands.el" t) (helpful-key "\344") (execute-extended-command nil "dwim-shell-commands-menu") (helpful-key "a") (execute-extended-command nil "dwim-shell-commands-menu" "dwim=") (execute-extended-command nil "dwim-shell-command" "dwim-shell-comm") (helpful-key "\303") (time-zones) (execute-extended-command nil "time-zones" "timezon") (cj/kill-buffer-or-bury-alive "christine-2025-09-04-henry-jovel-construction-34550.pdf") (cj/kill-buffer-or-bury-alive "expenses-real-estate.org") (find-file "~/projects/jr-estate/event-candidates.org" t)))
(setq set-variable-value-history 'nil)
(setq custom-variable-history 'nil)
-(setq query-replace-history '("Craig" "Speaker A" "Claire" "Speaker B" "Justin Ratowsky" "Speaker C" "Craig Ratowsky" "Craig Jennings" "" "*" "Shane" "Christine" "Laura Smetanick" ", 2025" "## " "##" "**" "Rosalea" "Rosalie" "Laura" "Christine Ciarmello" "SOV" "sop" "Jonathan Shultis" "Jonathan Schultis"))
+(setq query-replace-history '("" #(" on Vimeo" 0 8 (dired-filename t) 8 9 (rear-nonsticky t dired-filename t)) ": " ": " "Claire: " "Craig:" "Craig Jennings" "Claire" "Craig" "Speaker A" "Speaker B" "Justin Ratowsky" "Speaker C" "Craig Ratowsky" "*" "Shane" "Christine" "Laura Smetanick" ", 2025" "## " "##" "**" "Rosalea" "Rosalie" "Laura"))
(setq read-expression-history '("mouse-trap-mode " "mouse-trap-mode-map" "(mouse-trap-mode)" "(mousetrap-mode)" "(list :major-mode major-mode
:profile (mouse-trap--get-profile-for-mode)
:allowed-categories (alist-get (mouse-trap--get-profile-for-mode) mouse-trap-profiles))" "(describe-keymap mouse-trap-mode-map)" " (describe-keymap mouse-trap-mode-map)" "(face-attribute 'cursor :background)" "(with-current-buffer (find-file-noselect \"~/test-cursor.txt\")
@@ -93,8 +157,8 @@ music-config.el.
(setq chime-calendar-url \"https://calendar.google.com/calendar/u/0/r\")
(chime-mode 1)
(message \"Reloaded chime from ~/code/chime.el\"))" "chime-calendar-url"))
-(setq minibuffer-history '("64k" "128k" "~/projects/finances/" "modules/dwim-shell-config.el" "~/.emacs.d/" "dwim-shell-command.el" "~/code/dwim-shell-command/" "Huntington Beach, CA" "~/projects/jr-estate/" "~/projects/danneel/" "masterpdfeditor5" "todo.org" "Jabra SPEAK 510 USB" "inbox/claire.vcf" "Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "Comes out guns a-blazing on the first sentence. Pretty impressive opening statement. " "nature-and-spirit-an-essay-in-ecstatic-na-robert-s-corrington" "second note. socrates section. " "testing notes now" "the-truth-about-the-world-basic-readings-james-rachels" "nothing else to note here. " "I was going to read Aristotle's polics. But they started without me. " "Bloody? yick. " "...developing Nations, heh. " "The Truth About the World_ Basic Readings - James Rachels.pdf" "Is there any other kind of note? " "Preface Note" "Preface" "this is the socrates section. " "the-truth-about-the-world" "hey there. just testing org-noter. " "The Truth About the World" "The Truth About the World - James Rachels" "early-init.el" "factotum" "Wolf Hall - Hilary Mantel" "New Orleans, LA" "docs/NOTES.org" "ratowsky_real_estate/2025-11-13-13-30-plan-discussion-with-laura.txt" "evince" "evincce" "zathura" "masterpdf5" "docs/workflows/session-wrap-up.org" "~/projects/claude-templates/" "~/code/chime.el/" "The Yellow Dog - Georges Simenon" "David Bowie/Hunky Dory - 1971/" "and" "assets/2025-08-01-Meeting_Notes.pdf"))
+(setq minibuffer-history '("proton" "modules/user-constants.el" "~/.emacs.d/" "Wolf Hall - Hilary Mantel" "Roberto Gini/Fantasia-Suites John Jenkins and his ‘most esteemed friend’ William Lawes/" "Oberlin Consort of Viols/5 and 6 part Fantasies of William Lawes/" "Baroque Sonatas.m3u" "Venice Classic Radio.m3u" "Radio Caprice Classical Lute.m3u" "BAGeL Radio.m3u" "Love and Rockets" "Love and Rockets/Earth Sun Moon (1987)/06 Lazy.flac" "Love and Rockets/" "Jabra SPEAK 510 USB" "inbox/RejectionNotice_0_async.pdf" "~/projects/jr-estate/" "Huntington Beach, CA" "docs/NOTES.org" "~/projects/finances/" "[ADM] Addendum No. 1.pdf" "64k" "128k" "modules/dwim-shell-config.el" "dwim-shell-command.el" "~/code/dwim-shell-command/" "~/projects/danneel/" "masterpdfeditor5" "todo.org" "inbox/claire.vcf" "Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "Comes out guns a-blazing on the first sentence. Pretty impressive opening statement. " "nature-and-spirit-an-essay-in-ecstatic-na-robert-s-corrington" "second note. socrates section. " "testing notes now" "the-truth-about-the-world-basic-readings-james-rachels" "nothing else to note here. " "I was going to read Aristotle's polics. But they started without me. " "Bloody? yick. " "...developing Nations, heh. " "The Truth About the World_ Basic Readings - James Rachels.pdf" "Is there any other kind of note? " "Preface Note" "Preface" "this is the socrates section. " "the-truth-about-the-world" "hey there. just testing org-noter. " "The Truth About the World" "The Truth About the World - James Rachels" "early-init.el" "factotum"))
(setq read-char-history '("yes"))
(setq face-name-history 'nil)
-(setq bookmark-history '("Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "The Truth About the World - James Rachels" "The Truth About the World_ Basic Readings - James Rachels.pdf" "The Truth About the World_ Basic Readings - James Rachels.pdf" #1="The Truth About the World_ Basic Readings - James Rachels.pdf" #1# "The Truth About the World_ Basic Readings - James Rachels.pdf" "The Truth About the World - James Rachels" "The Truth About the World - James Rachels" "The Truth About the World_ Basic Readings - James Rachels" "The Truth About the World - James Rachels" #2="The Truth About the World - James Rachels" #2# "The Truth About the World - James Rachels" "The Truth About the World - James Rachels" "Heidegger's Later Writings - Lee Braver" "The Truth About the World_ Basic Readings - James Rachels" "The Truth About the World_ Basic Readings - James Rachels" "Wolf Hall - Hilary Mantel" "Wolf Hall - Hilary Mantel" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "Wolf Hall - Hilary Mantel" "Essex Dogs - Dan Jones" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "Wittgenstein's Vienna - Allan Janik.pdf" "Zizek and Heidegger_ The Question Concerni - Thomas Brockelman.pdf" "The Concept of Law - H. L. A. Hart.pdf"))
-(setq file-name-history '("~/code/dwim-shell-command/dwim-shell-commands.el" "/tmp/claude-prompt-2f3c0e6a-6bd2-4d0f-b0bf-450660b379a9.md" "~/projects/jr-estate/event-candidates.org" "/tmp/claude-prompt-66f67f73-3dcc-4317-bd46-afd6f723a60a.md" "/tmp/claude-prompt-7cf290fa-2406-4771-bed4-2eaddf354c07.md" "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" "/tmp/claude-prompt-0e67f38d-d20e-4542-815a-1f937fd962e3.md" "~/.emacs.d/docs/org-noter-workflow-spec.org" "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " "~/projects/jr-estate/docs/draft-email-to-laura-hb-trip.org" "~/sync/books/Georges Simenon/A Crime in Holland (2806)/A Crime in Holland - Georges Simenon.epub" "~/projects/clipper/docs/tenant-comparison-2025-11.org" "~/documents/dropbox/Carrollton Construction/craig-draft-to-jonathan" "~/projects/danneel/inbox/laura's flights to hb.txt" "~/projects/danneel/inbox/car rental.txt" "~/projects/danneel/inbox/" "~/projects/documents/inbox" "~/.config/garglk.ini" "~/sync/org/text.games/sherlock-r26-s880127.z5" "~/sync/org/text.games/sherlock.riddle.of.the.crown.jewels.1987.z5" "~/sync/org/text.games/nameless.2012.z8" "~/.profile" "~/runme.sh" "~/.emacs.d/modules/system-utils.el" "~/test.txt" "~/projects/jr-estate/inbox/text-conversation-justin-craig-re-laura's-arrival.txt" "~/projects/jr-estate/inbox/justin-craig-craig-3:39-pm.org" "~/videos/Global Finance Pulse-The Prof G - Deficits & Debt - Will They Crash the Economy?.webm" "~/videos/politics/" "~/code/org-drill/test/org-drill-test.el" "~/.emacs.d/.time-zones.el" "~/code/org-drill/todo.org" "~/projects/jr-estate/inbox/" "~rpc/" "~/projects/claude-templates" "/tmp/claude-prompt-bdd8c73a-233d-4598-ba97-59bf1238a772.md" "/tmp/claude-prompt-e8677ff5-14bf-4254-a529-6e471dd88347.md" "/tmp/claude-prompt-7940afe3-09f6-49e8-9793-20a616c04b5e.md" "/tmp/claude-prompt-f6799835-f2d0-4cfa-ab66-53f90407667b.md" "/tmp/claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.md" "~/projects/jr-estate/jr_info/secrets/original/" "~/projects/jr-estate/email-laura-closing-costs.txt" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txt" "/tmp/claude-prompt-7c79b988-8b14-420f-87b5-2f9a2c725c37.md" "~/code/archsetup/docs/archsetup-v2mom.org" "~/downloads/goldens-book-issues.org" "/tmp/claude-prompt-48fc618e-a826-43e0-aa0e-57b679845ded.md" "~/.emacs.d/docs/NOTES.org" "~/projects/danneel/inbox" "~/.authinfo.gpg"))
+(setq bookmark-history '("Wolf Hall - Hilary Mantel" #1="Wolf Hall - Hilary Mantel" #1# #1# #1# #1# "Wolf Hall - Hilary Mantel" "Essex Dogs - Dan Jones" "Nature and Spirit_ An Essay in Ecstatic Na - Robert S. Corrington.pdf" "The Truth About the World - James Rachels" "The Truth About the World_ Basic Readings - James Rachels.pdf" "The Truth About the World_ Basic Readings - James Rachels.pdf" #2="The Truth About the World_ Basic Readings - James Rachels.pdf" #2# "The Truth About the World_ Basic Readings - James Rachels.pdf" "The Truth About the World - James Rachels" "The Truth About the World - James Rachels" "The Truth About the World_ Basic Readings - James Rachels" "The Truth About the World - James Rachels" #3="The Truth About the World - James Rachels" #3# "The Truth About the World - James Rachels" "The Truth About the World - James Rachels" "Heidegger's Later Writings - Lee Braver" "The Truth About the World_ Basic Readings - James Rachels" "The Truth About the World_ Basic Readings - James Rachels" "Wolf Hall - Hilary Mantel" "Wolf Hall - Hilary Mantel" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "Wolf Hall - Hilary Mantel" "Essex Dogs - Dan Jones" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "The Yellow Dog - Georges Simenon" "Wittgenstein's Vienna - Allan Janik.pdf" "Zizek and Heidegger_ The Question Concerni - Thomas Brockelman.pdf" "The Concept of Law - H. L. A. Hart.pdf"))
+(setq file-name-history '("~/.emacs.d/modules/calendar-sync.el" "~/archive/magic/Daniel Madison System/" "~/archive/magic/Daniel Madison Induction" "~/archive/magic/Daniel Madison Expert" "~/projects/finances/inbox/Danneel-street-hoa-payment.eml" "~/sync/org/text.games/planetfall.1983.z3" "~/projects/jr-estate/assets" "~/projects/jr-estate/inbox/" "~/code/dwim-shell-command/dwim-shell-commands.el" "/tmp/claude-prompt-2f3c0e6a-6bd2-4d0f-b0bf-450660b379a9.md" "~/projects/jr-estate/event-candidates.org" "/tmp/claude-prompt-66f67f73-3dcc-4317-bd46-afd6f723a60a.md" "/tmp/claude-prompt-7cf290fa-2406-4771-bed4-2eaddf354c07.md" "~/projects/jr-estate/inbox/kelly-pacific-dream-painting.vcf" "/tmp/claude-prompt-0e67f38d-d20e-4542-815a-1f937fd962e3.md" "~/.emacs.d/docs/org-noter-workflow-spec.org" "~/projects/jr-estate/inbox/text-message-exchange-craig-justin-2025-11-20 Thu @ 18:21:09 -0800 " "~/projects/jr-estate/docs/draft-email-to-laura-hb-trip.org" "~/sync/books/Georges Simenon/A Crime in Holland (2806)/A Crime in Holland - Georges Simenon.epub" "~/projects/clipper/docs/tenant-comparison-2025-11.org" "~/documents/dropbox/Carrollton Construction/craig-draft-to-jonathan" "~/projects/danneel/inbox/laura's flights to hb.txt" "~/projects/danneel/inbox/car rental.txt" "~/projects/danneel/inbox/" "~/projects/documents/inbox" "~/.config/garglk.ini" "~/sync/org/text.games/sherlock-r26-s880127.z5" "~/sync/org/text.games/sherlock.riddle.of.the.crown.jewels.1987.z5" "~/sync/org/text.games/nameless.2012.z8" "~/.profile" "~/runme.sh" "~/.emacs.d/modules/system-utils.el" "~/test.txt" "~/projects/jr-estate/inbox/text-conversation-justin-craig-re-laura's-arrival.txt" "~/projects/jr-estate/inbox/justin-craig-craig-3:39-pm.org" "~/videos/Global Finance Pulse-The Prof G - Deficits & Debt - Will They Crash the Economy?.webm" "~/videos/politics/" "~/code/org-drill/test/org-drill-test.el" "~/.emacs.d/.time-zones.el" "~/code/org-drill/todo.org" "~rpc/" "~/projects/claude-templates" "/tmp/claude-prompt-bdd8c73a-233d-4598-ba97-59bf1238a772.md" "/tmp/claude-prompt-e8677ff5-14bf-4254-a529-6e471dd88347.md" "/tmp/claude-prompt-7940afe3-09f6-49e8-9793-20a616c04b5e.md" "/tmp/claude-prompt-f6799835-f2d0-4cfa-ab66-53f90407667b.md" "/tmp/claude-prompt-19cf8319-da35-4d45-8489-2ea90abe3a64.md" "~/projects/jr-estate/jr_info/secrets/original/" "~/projects/jr-estate/email-laura-closing-costs.txt" "~/projects/jr-estate/ratowsky_real_estate/2025-11-07-12-25-phone-call-closing-costs-discussion.txt"))
diff --git a/init.el b/init.el
index 1f67b782..d39b659b 100644
--- a/init.el
+++ b/init.el
@@ -114,11 +114,15 @@
(require 'org-export-config)
;; (require 'org-gcal-config) ;; DISABLED: Replaced by calendar-sync.el (one-way sync)
-;; Google Calendar sync (one-way: Google → Org)
-(setq calendar-sync-ics-url "https://calendar.google.com/calendar/ical/craigmartinjennings%40gmail.com/private-1dad154d6a2100e755f76e2d0502f6aa/basic.ics")
+;; Calendar sync (one-way: Google/Proton → Org)
+(setq calendar-sync-calendars
+ `((:name "google"
+ :url "https://calendar.google.com/calendar/ical/craigmartinjennings%40gmail.com/private-1dad154d6a2100e755f76e2d0502f6aa/basic.ics"
+ :file ,gcal-file)
+ (:name "proton"
+ :url "https://calendar.proton.me/api/calendar/v1/url/MpLtuwsUNoygyA_60GvJE5cz0hbREbrAPBEJoWDRpFEstnmzmEMDb7sjLzkY8kbkF10A7Be3wGKB1-vqaLf-pw==/calendar.ics?CacheKey=LrB9NG5Vfqp5p2sy90H13g%3D%3D&PassphraseKey=sURqFfACPM21d6AXSeaEXYCruimvSb8t0ce1vuxRAXk%3D"
+ :file ,pcal-file)))
(require 'calendar-sync)
-;; Uncomment to enable auto-sync every 15 minutes:
-;; (calendar-sync-start)
(require 'org-refile-config) ;; refile org-branches
(require 'org-roam-config) ;; personal knowledge management in org mode
diff --git a/modules/calendar-sync.el b/modules/calendar-sync.el
index dbea95c9..8f71c709 100644
--- a/modules/calendar-sync.el
+++ b/modules/calendar-sync.el
@@ -1,25 +1,26 @@
-;;; calendar-sync.el --- Simple Google Calendar sync via .ics -*- lexical-binding: t; -*-
+;;; calendar-sync.el --- Multi-calendar sync via .ics -*- lexical-binding: t; -*-
;; Author: Craig Jennings <c@cjennings.net>
;; Created: 2025-11-16
;;; Commentary:
-;; Simple, reliable one-way sync from Google Calendar to Org mode.
-;; Downloads .ics file from Google Calendar private URL and converts
-;; to Org format. No OAuth, no API complexity, just file conversion.
+;; Simple, reliable one-way sync from multiple calendars to Org mode.
+;; Downloads .ics files from calendar URLs (Google, Proton, etc.) and
+;; converts to Org format. No OAuth, no API complexity, just file conversion.
;;
;; Features:
+;; - Multi-calendar support (sync multiple calendars to separate files)
;; - Pure Emacs Lisp .ics parser (no external dependencies)
;; - Recurring event support (RRULE expansion)
;; - Timer-based automatic sync (every 60 minutes, configurable)
;; - Self-contained in .emacs.d (no cron, portable across machines)
-;; - Read-only (can't corrupt Google Calendar)
+;; - Read-only (can't corrupt source calendars)
;; - Works with chime.el for event notifications
;;
;; Recurring Events (RRULE):
;;
-;; Google Calendar recurring events are defined once with an RRULE
+;; Calendar recurring events are defined once with an RRULE
;; (recurrence rule) rather than as individual event instances. This
;; module expands recurring events into individual org entries.
;;
@@ -32,14 +33,6 @@
;; naturally fall off after 3 months, and new future events appear
;; as you approach them.
;;
-;; Example: If today is 2025-11-18, events are expanded from
-;; 2025-08-18 to 2026-11-18. When you sync on 2026-01-01, the
-;; window shifts to 2025-10-01 to 2027-01-01 automatically.
-;;
-;; This approach requires no state tracking and naturally handles
-;; the "year boundary" problem - there is no boundary to cross,
-;; the window just moves forward with each sync.
-;;
;; Supported RRULE patterns:
;; - FREQ=DAILY: Daily events
;; - FREQ=WEEKLY;BYDAY=MO,WE,FR: Weekly on specific days
@@ -50,43 +43,57 @@
;; - COUNT: Maximum occurrences (combined with date range limit)
;;
;; Setup:
-;; 1. Get your Google Calendar private .ics URL:
-;; - Open Google Calendar → Settings → Your Calendar → Integrate calendar
-;; - Copy the "Secret address in iCal format" URL
+;; 1. Configure calendars in your init.el:
+;; (setq calendar-sync-calendars
+;; '((:name "google"
+;; :url "https://calendar.google.com/calendar/ical/.../basic.ics"
+;; :file gcal-file)
+;; (:name "proton"
+;; :url "https://calendar.proton.me/api/calendar/v1/url/.../calendar.ics"
+;; :file pcal-file)))
;;
-;; 2. Configure in your init.el:
-;; (setq calendar-sync-ics-url "https://calendar.google.com/calendar/ical/YOUR_PRIVATE_URL/basic.ics")
+;; 2. Load and start:
;; (require 'calendar-sync)
;; (calendar-sync-start)
;;
;; 3. Add to org-agenda (optional):
-;; (add-to-list 'org-agenda-files calendar-sync-file)
+;; (dolist (cal calendar-sync-calendars)
+;; (add-to-list 'org-agenda-files (plist-get cal :file)))
;;
;; Usage:
-;; - M-x calendar-sync-now ; Manual sync
+;; - M-x calendar-sync-now ; Sync all or select specific calendar
;; - M-x calendar-sync-start ; Start auto-sync
;; - M-x calendar-sync-stop ; Stop auto-sync
;; - M-x calendar-sync-toggle ; Toggle auto-sync
+;; - M-x calendar-sync-status ; Show sync status for all calendars
;;; Code:
(require 'org)
-(require 'user-constants) ; For gcal-file path
+(require 'user-constants) ; For gcal-file, pcal-file paths
;;; Configuration
-(defvar calendar-sync-ics-url nil
- "Google Calendar private .ics URL.
-Get this from Google Calendar Settings → Integrate calendar → Secret address in iCal format.")
+(defvar calendar-sync-calendars nil
+ "List of calendars to sync.
+Each calendar is a plist with the following keys:
+ :name - Display name for the calendar (used in logs and prompts)
+ :url - URL to fetch .ics file from
+ :file - Output file path for org format
+
+Example:
+ (setq calendar-sync-calendars
+ \\='((:name \"google\"
+ :url \"https://calendar.google.com/calendar/ical/.../basic.ics\"
+ :file gcal-file)
+ (:name \"proton\"
+ :url \"https://calendar.proton.me/api/calendar/v1/url/.../calendar.ics\"
+ :file pcal-file)))")
(defvar calendar-sync-interval-minutes 60
"Sync interval in minutes.
Default: 60 minutes (1 hour).")
-(defvar calendar-sync-file gcal-file
- "Location of synced calendar file.
-Defaults to gcal-file from user-constants.")
-
(defvar calendar-sync-auto-start t
"Whether to automatically start calendar sync when module loads.
If non-nil, sync starts automatically when calendar-sync is loaded.
@@ -105,11 +112,12 @@ Default: 12 months. This provides a full year of future events.")
(defvar calendar-sync--timer nil
"Timer object for automatic syncing.")
-(defvar calendar-sync--last-sync-time nil
- "Time of last successful sync.")
-
-(defvar calendar-sync--last-error nil
- "Last sync error message, if any.")
+(defvar calendar-sync--calendar-states (make-hash-table :test 'equal)
+ "Per-calendar sync state.
+Hash table mapping calendar name (string) to state plist with:
+ :last-sync - Time of last successful sync
+ :status - Symbol: ok, error, or syncing
+ :last-error - Error message string, or nil")
(defvar calendar-sync--last-timezone-offset nil
"Timezone offset in seconds from UTC at last sync.
@@ -155,9 +163,15 @@ Example: -21600 → 'UTC-6' or 'UTC-6:00'."
(defun calendar-sync--save-state ()
"Save sync state to disk for persistence across sessions."
- (let ((state `((timezone-offset . ,calendar-sync--last-timezone-offset)
- (last-sync-time . ,calendar-sync--last-sync-time)))
- (dir (file-name-directory calendar-sync--state-file)))
+ (let* ((calendar-states-alist
+ (let ((result '()))
+ (maphash (lambda (name state)
+ (push (cons name state) result))
+ calendar-sync--calendar-states)
+ result))
+ (state `((timezone-offset . ,calendar-sync--last-timezone-offset)
+ (calendar-states . ,calendar-states-alist)))
+ (dir (file-name-directory calendar-sync--state-file)))
(unless (file-directory-p dir)
(make-directory dir t))
(with-temp-file calendar-sync--state-file
@@ -172,11 +186,22 @@ Example: -21600 → 'UTC-6' or 'UTC-6:00'."
(let ((state (read (current-buffer))))
(setq calendar-sync--last-timezone-offset
(alist-get 'timezone-offset state))
- (setq calendar-sync--last-sync-time
- (alist-get 'last-sync-time state))))
+ ;; Load per-calendar states
+ (let ((cal-states (alist-get 'calendar-states state)))
+ (clrhash calendar-sync--calendar-states)
+ (dolist (entry cal-states)
+ (puthash (car entry) (cdr entry) calendar-sync--calendar-states)))))
(error
(cj/log-silently "calendar-sync: Error loading state: %s" (error-message-string err))))))
+(defun calendar-sync--get-calendar-state (calendar-name)
+ "Get state plist for CALENDAR-NAME, or nil if not found."
+ (gethash calendar-name calendar-sync--calendar-states))
+
+(defun calendar-sync--set-calendar-state (calendar-name state)
+ "Set STATE plist for CALENDAR-NAME."
+ (puthash calendar-name state calendar-sync--calendar-states))
+
;;; Line Ending Normalization
(defun calendar-sync--normalize-line-endings (content)
@@ -636,7 +661,7 @@ Recurring events are expanded into individual occurrences."
(calendar-sync--event-start-time b)))))
(org-entries (mapcar #'calendar-sync--event-to-org sorted-events)))
(if org-entries
- (concat "# Google Calendar Events\n\n"
+ (concat "# Calendar Events\n\n"
(string-join org-entries "\n\n")
"\n")
nil)))
@@ -681,38 +706,116 @@ invoked when the fetch completes, either successfully or with an error."
(cj/log-silently "calendar-sync: Fetch error: %s" calendar-sync--last-error)
(funcall callback nil))))
-(defun calendar-sync--write-file (content)
- "Write CONTENT to `calendar-sync-file'.
+(defun calendar-sync--write-file (content file)
+ "Write CONTENT to FILE.
Creates parent directories if needed."
- (let ((dir (file-name-directory calendar-sync-file)))
+ (let ((dir (file-name-directory file)))
(unless (file-directory-p dir)
(make-directory dir t)))
- (with-temp-file calendar-sync-file
- (insert content))
- (message "calendar-sync: Updated %s" calendar-sync-file))
-
-;;;###autoload
-(defun calendar-sync-now ()
- "Sync Google Calendar now asynchronously.
-Downloads .ics file and updates org file without blocking Emacs.
-Tracks timezone for automatic re-sync on timezone changes."
- (interactive)
- (if (not calendar-sync-ics-url)
- (message "calendar-sync: Please set calendar-sync-ics-url")
- (message "calendar-sync: Syncing...")
+ (with-temp-file file
+ (insert content)))
+
+;;; Single Calendar Sync
+
+(defun calendar-sync--sync-calendar (calendar)
+ "Sync a single CALENDAR asynchronously.
+CALENDAR is a plist with :name, :url, and :file keys.
+Updates calendar state and saves to disk on completion."
+ (let ((name (plist-get calendar :name))
+ (url (plist-get calendar :url))
+ (file (plist-get calendar :file)))
+ ;; Mark as syncing
+ (calendar-sync--set-calendar-state name '(:status syncing))
+ (cj/log-silently "calendar-sync: [%s] Syncing..." name)
(calendar-sync--fetch-ics
- calendar-sync-ics-url
+ url
(lambda (ics-content)
(let ((org-content (and ics-content (calendar-sync--parse-ics ics-content))))
(if org-content
(progn
- (calendar-sync--write-file org-content)
- (setq calendar-sync--last-sync-time (current-time))
- (setq calendar-sync--last-timezone-offset (calendar-sync--current-timezone-offset))
- (setq calendar-sync--last-error nil)
+ (calendar-sync--write-file org-content file)
+ (calendar-sync--set-calendar-state
+ name
+ (list :status 'ok
+ :last-sync (current-time)
+ :last-error nil))
+ (setq calendar-sync--last-timezone-offset
+ (calendar-sync--current-timezone-offset))
(calendar-sync--save-state)
- (message "calendar-sync: Sync complete"))
- (message "calendar-sync: Sync failed (see *Messages* for details)")))))))
+ (message "calendar-sync: [%s] Sync complete → %s" name file))
+ (calendar-sync--set-calendar-state
+ name
+ (list :status 'error
+ :last-sync (plist-get (calendar-sync--get-calendar-state name) :last-sync)
+ :last-error "Parse failed"))
+ (calendar-sync--save-state)
+ (message "calendar-sync: [%s] Sync failed (see *Messages*)" name)))))))
+
+(defun calendar-sync--sync-all-calendars ()
+ "Sync all configured calendars asynchronously.
+Each calendar syncs in parallel."
+ (if (null calendar-sync-calendars)
+ (message "calendar-sync: No calendars configured (set calendar-sync-calendars)")
+ (message "calendar-sync: Syncing %d calendar(s)..." (length calendar-sync-calendars))
+ (dolist (calendar calendar-sync-calendars)
+ (calendar-sync--sync-calendar calendar))))
+
+(defun calendar-sync--calendar-names ()
+ "Return list of configured calendar names."
+ (mapcar (lambda (cal) (plist-get cal :name)) calendar-sync-calendars))
+
+(defun calendar-sync--get-calendar-by-name (name)
+ "Find calendar plist by NAME, or nil if not found."
+ (cl-find-if (lambda (cal) (string= (plist-get cal :name) name))
+ calendar-sync-calendars))
+
+;;;###autoload
+(defun calendar-sync-now (&optional calendar-name)
+ "Sync calendar(s) now asynchronously.
+When called interactively, prompts to select a specific calendar or all.
+When called non-interactively with CALENDAR-NAME, syncs that calendar.
+When called non-interactively with nil, syncs all calendars."
+ (interactive
+ (list (when calendar-sync-calendars
+ (let ((choices (cons "all" (calendar-sync--calendar-names))))
+ (completing-read "Sync calendar: " choices nil t nil nil "all")))))
+ (cond
+ ((null calendar-sync-calendars)
+ (message "calendar-sync: No calendars configured (set calendar-sync-calendars)"))
+ ((or (null calendar-name) (string= calendar-name "all"))
+ (calendar-sync--sync-all-calendars))
+ (t
+ (let ((calendar (calendar-sync--get-calendar-by-name calendar-name)))
+ (if calendar
+ (calendar-sync--sync-calendar calendar)
+ (message "calendar-sync: Calendar '%s' not found" calendar-name))))))
+
+;;;###autoload
+(defun calendar-sync-status ()
+ "Display sync status for all configured calendars."
+ (interactive)
+ (if (null calendar-sync-calendars)
+ (message "calendar-sync: No calendars configured")
+ (let ((status-lines '()))
+ (dolist (calendar calendar-sync-calendars)
+ (let* ((name (plist-get calendar :name))
+ (file (plist-get calendar :file))
+ (state (calendar-sync--get-calendar-state name))
+ (status (or (plist-get state :status) 'never))
+ (last-sync (plist-get state :last-sync))
+ (last-error (plist-get state :last-error))
+ (status-str
+ (pcase status
+ ('ok (format "✓ %s" (if last-sync
+ (format-time-string "%Y-%m-%d %H:%M" last-sync)
+ "unknown")))
+ ('error (format "✗ %s" (or last-error "error")))
+ ('syncing "⟳ syncing...")
+ ('never "— never synced"))))
+ (push (format " %s: %s → %s" name status-str (abbreviate-file-name file))
+ status-lines)))
+ (message "calendar-sync status:\n%s"
+ (string-join (nreverse status-lines) "\n")))))
;;; Timer management
@@ -726,27 +829,28 @@ Checks for timezone changes and triggers re-sync if detected."
(calendar-sync--current-timezone-offset))))
(message "calendar-sync: Timezone change detected (%s → %s), re-syncing..."
old-tz new-tz)))
- (calendar-sync-now))
+ (calendar-sync--sync-all-calendars))
;;;###autoload
(defun calendar-sync-start ()
"Start automatic calendar syncing.
-Syncs immediately, then every `calendar-sync-interval-minutes' minutes."
+Syncs all calendars immediately, then every `calendar-sync-interval-minutes'."
(interactive)
(when calendar-sync--timer
(cancel-timer calendar-sync--timer))
- (if (not calendar-sync-ics-url)
- (message "calendar-sync: Please set calendar-sync-ics-url before starting")
+ (if (null calendar-sync-calendars)
+ (message "calendar-sync: No calendars configured (set calendar-sync-calendars)")
;; Sync immediately
- (calendar-sync-now)
+ (calendar-sync--sync-all-calendars)
;; Start timer for future syncs (convert minutes to seconds)
(let ((interval-seconds (* calendar-sync-interval-minutes 60)))
(setq calendar-sync--timer
(run-at-time interval-seconds
interval-seconds
#'calendar-sync--sync-timer-function)))
- (message "calendar-sync: Auto-sync started (every %d minutes)"
- calendar-sync-interval-minutes)))
+ (message "calendar-sync: Auto-sync started (every %d minutes, %d calendars)"
+ calendar-sync-interval-minutes
+ (length calendar-sync-calendars))))
;;;###autoload
(defun calendar-sync-stop ()
@@ -771,6 +875,7 @@ Syncs immediately, then every `calendar-sync-interval-minutes' minutes."
(defvar-keymap cj/calendar-map
:doc "Keymap for calendar synchronization operations"
"s" #'calendar-sync-now
+ "i" #'calendar-sync-status
"t" #'calendar-sync-toggle
"S" #'calendar-sync-start
"x" #'calendar-sync-stop)
@@ -783,6 +888,7 @@ Syncs immediately, then every `calendar-sync-interval-minutes' minutes."
(which-key-add-key-based-replacements
"C-; g" "calendar sync menu"
"C-; g s" "sync now"
+ "C-; g i" "sync status"
"C-; g t" "toggle auto-sync"
"C-; g S" "start auto-sync"
"C-; g x" "stop auto-sync")))
@@ -793,7 +899,7 @@ Syncs immediately, then every `calendar-sync-interval-minutes' minutes."
(calendar-sync--load-state)
;; Check for timezone change on startup
-(when (and calendar-sync-ics-url
+(when (and calendar-sync-calendars
(calendar-sync--timezone-changed-p))
(let ((old-tz (calendar-sync--format-timezone-offset
calendar-sync--last-timezone-offset))
@@ -806,9 +912,9 @@ Syncs immediately, then every `calendar-sync-interval-minutes' minutes."
;; User can manually sync or it will happen on next timer tick if auto-sync is enabled
))
-;; Start auto-sync if enabled and URL is configured
+;; Start auto-sync if enabled and calendars are configured
;; Syncs immediately then every calendar-sync-interval-minutes (default: 60 minutes)
-(when (and calendar-sync-auto-start calendar-sync-ics-url)
+(when (and calendar-sync-auto-start calendar-sync-calendars)
(calendar-sync-start))
(provide 'calendar-sync)
diff --git a/modules/org-agenda-config.el b/modules/org-agenda-config.el
index de8a89c8..4be4db9e 100644
--- a/modules/org-agenda-config.el
+++ b/modules/org-agenda-config.el
@@ -142,7 +142,7 @@ improves performance from several seconds to instant."
(setq cj/org-agenda-files-building t)
(let ((start-time (current-time)))
;; Reset org-agenda-files to base files
- (setq org-agenda-files (list inbox-file schedule-file gcal-file))
+ (setq org-agenda-files (list inbox-file schedule-file gcal-file pcal-file))
;; Check all projects for scheduled tasks
(cj/add-files-to-org-agenda-files-list projects-dir)
@@ -335,7 +335,7 @@ This allows a line to show in an agenda without being scheduled or a deadline."
:init
;; Initialize org-agenda-files with base files before chime loads
;; The full list will be built asynchronously later
- (setq org-agenda-files (list inbox-file schedule-file gcal-file))
+ (setq org-agenda-files (list inbox-file schedule-file gcal-file pcal-file))
;; Debug mode (keep set to nil, but available for troubleshooting)
(setq chime-debug nil)
diff --git a/modules/user-constants.el b/modules/user-constants.el
index c4c7a106..3b248ddd 100644
--- a/modules/user-constants.el
+++ b/modules/user-constants.el
@@ -131,6 +131,10 @@ Used by transcription module and other audio-related functionality.")
"The location of the org file containing Google Calendar information.
Stored in .emacs.d/data/ so each machine syncs independently from Google Calendar.")
+(defvar pcal-file (expand-file-name "data/pcal.org" user-emacs-directory)
+ "The location of the org file containing Proton Calendar information.
+Stored in .emacs.d/data/ so each machine syncs independently from Proton Calendar.")
+
(defvar reference-file (expand-file-name "reference.org" org-dir)
"The location of the org file containing reference information.")
diff --git a/tests/test-calendar-sync--expand-weekly.el b/tests/test-calendar-sync--expand-weekly.el
index e4e5b738..fe333c98 100644
--- a/tests/test-calendar-sync--expand-weekly.el
+++ b/tests/test-calendar-sync--expand-weekly.el
@@ -122,7 +122,8 @@
(unwind-protect
(let* ((start-date (test-calendar-sync-time-days-from-now 1 10 0))
(end-date (test-calendar-sync-time-days-from-now 1 11 0))
- (until-date (test-calendar-sync-time-days-from-now 60 0 0))
+ ;; UNTIL must be date-only (3 elements) for calendar-sync--before-date-p
+ (until-date (test-calendar-sync-time-date-only 60))
(base-event (list :summary "Time-Limited Event"
:start start-date
:end end-date))
@@ -253,7 +254,8 @@
(unwind-protect
(let* ((start-date (test-calendar-sync-time-days-ago 100 10 0))
(end-date (test-calendar-sync-time-days-ago 100 11 0))
- (until-date (test-calendar-sync-time-days-ago 50 0 0))
+ ;; UNTIL must be date-only (3 elements) for calendar-sync--before-date-p
+ (until-date (test-calendar-sync-time-date-only-ago 50))
(base-event (list :summary "Past Event"
:start start-date
:end end-date))
diff --git a/tests/test-calendar-sync-properties.el b/tests/test-calendar-sync-properties.el
new file mode 100644
index 00000000..6054fc5e
--- /dev/null
+++ b/tests/test-calendar-sync-properties.el
@@ -0,0 +1,239 @@
+;;; test-calendar-sync-properties.el --- Property-based tests for calendar-sync -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Property-based tests for RRULE expansion functions.
+;; These tests verify invariants hold across randomly generated inputs,
+;; complementing the example-based tests in other test files.
+;;
+;; Each test runs multiple trials with random parameters to explore
+;; the input space and find edge cases that example-based tests miss.
+;;
+;; Properties tested:
+;; 1. COUNT always limits total occurrences
+;; 2. UNTIL date bounds all occurrences
+;; 3. BYDAY constrains weekly occurrences to specified weekdays
+;; 4. INTERVAL creates correct spacing between occurrences
+;; 5. All occurrences fall within the date range
+;; 6. Expansion is deterministic (same inputs → same outputs)
+
+;;; Code:
+
+(require 'ert)
+(require 'calendar-sync)
+(require 'testutil-calendar-sync)
+
+(defconst test-calendar-sync-property-trials 30
+ "Number of random trials to run for each property test.
+Higher values give more confidence but slower tests.")
+
+;;; Property 1: COUNT Ceiling
+
+(ert-deftest test-calendar-sync-property-count-limits-daily ()
+ "Property: COUNT parameter limits daily occurrences.
+For any COUNT value N, expansion never produces more than N occurrences."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((count (1+ (random 20)))
+ (start-date (test-calendar-sync-random-future-date))
+ (base-event (list :summary "Daily Test" :start start-date))
+ (rrule (list :freq 'daily :interval 1 :count count))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-daily base-event rrule range)))
+ (should (<= (length occurrences) count)))))
+
+(ert-deftest test-calendar-sync-property-count-limits-weekly ()
+ "Property: COUNT parameter limits weekly occurrences.
+For any COUNT value N, expansion never produces more than N occurrences."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((count (1+ (random 20)))
+ (weekdays (test-calendar-sync-random-weekday-subset))
+ (start-date (test-calendar-sync-random-future-date))
+ (base-event (list :summary "Weekly Test" :start start-date))
+ (rrule (list :freq 'weekly :byday weekdays :interval 1 :count count))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-weekly base-event rrule range)))
+ (should (<= (length occurrences) count)))))
+
+(ert-deftest test-calendar-sync-property-count-limits-monthly ()
+ "Property: COUNT parameter limits monthly occurrences."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((count (1+ (random 15)))
+ (start-date (test-calendar-sync-random-future-date))
+ (base-event (list :summary "Monthly Test" :start start-date))
+ (rrule (list :freq 'monthly :interval 1 :count count))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-monthly base-event rrule range)))
+ (should (<= (length occurrences) count)))))
+
+(ert-deftest test-calendar-sync-property-count-limits-yearly ()
+ "Property: COUNT parameter limits yearly occurrences."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((count (1+ (random 5)))
+ (start-date (test-calendar-sync-random-future-date))
+ (base-event (list :summary "Yearly Test" :start start-date))
+ (rrule (list :freq 'yearly :interval 1 :count count))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-yearly base-event rrule range)))
+ (should (<= (length occurrences) count)))))
+
+;;; Property 2: UNTIL Boundary
+
+(ert-deftest test-calendar-sync-property-until-bounds-daily ()
+ "Property: No daily occurrence starts on or after UNTIL date."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (until-days (+ 10 (random 60)))
+ ;; UNTIL must be date-only (3 elements) for calendar-sync--before-date-p
+ (until-date (test-calendar-sync-time-date-only until-days))
+ (base-event (list :summary "Until Test" :start start-date))
+ (rrule (list :freq 'daily :interval 1 :until until-date))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-daily base-event rrule range)))
+ (dolist (occ occurrences)
+ (let ((occ-start (plist-get occ :start)))
+ (should (calendar-sync--before-date-p
+ (list (nth 0 occ-start) (nth 1 occ-start) (nth 2 occ-start))
+ until-date)))))))
+
+(ert-deftest test-calendar-sync-property-until-bounds-weekly ()
+ "Property: No weekly occurrence starts on or after UNTIL date."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (until-days (+ 14 (random 60)))
+ ;; UNTIL must be date-only (3 elements) for calendar-sync--before-date-p
+ (until-date (test-calendar-sync-time-date-only until-days))
+ (weekdays (test-calendar-sync-random-weekday-subset))
+ (base-event (list :summary "Until Test" :start start-date))
+ (rrule (list :freq 'weekly :byday weekdays :interval 1 :until until-date))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-weekly base-event rrule range)))
+ (dolist (occ occurrences)
+ (let ((occ-start (plist-get occ :start)))
+ (should (calendar-sync--before-date-p
+ (list (nth 0 occ-start) (nth 1 occ-start) (nth 2 occ-start))
+ until-date)))))))
+
+;;; Property 3: BYDAY Constraint
+
+(ert-deftest test-calendar-sync-property-byday-constrains-weekdays ()
+ "Property: Weekly occurrences only fall on BYDAY weekdays.
+Every generated occurrence must be on one of the specified weekdays."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((weekdays (test-calendar-sync-random-weekday-subset))
+ (weekday-nums (mapcar #'calendar-sync--weekday-to-number weekdays))
+ (start-date (test-calendar-sync-random-future-date))
+ (base-event (list :summary "BYDAY Test" :start start-date))
+ (rrule (list :freq 'weekly :byday weekdays :interval 1))
+ (range (test-calendar-sync-narrow-range))
+ (occurrences (calendar-sync--expand-weekly base-event rrule range)))
+ (dolist (occ occurrences)
+ (let* ((occ-start (plist-get occ :start))
+ (occ-weekday (calendar-sync--date-weekday
+ (list (nth 0 occ-start) (nth 1 occ-start) (nth 2 occ-start)))))
+ (should (member occ-weekday weekday-nums)))))))
+
+;;; Property 4: INTERVAL Spacing
+
+(ert-deftest test-calendar-sync-property-interval-spacing-daily ()
+ "Property: Daily occurrences are spaced INTERVAL days apart.
+Consecutive occurrences should be exactly INTERVAL days apart."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((interval (1+ (random 5)))
+ (start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (base-event (list :summary "Interval Test" :start start-date))
+ (rrule (list :freq 'daily :interval interval :count 10))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-daily base-event rrule range)))
+ (when (> (length occurrences) 1)
+ (let ((dates (mapcar (lambda (o) (plist-get o :start)) occurrences)))
+ (cl-loop for i from 0 below (1- (length dates))
+ for d1 = (nth i dates)
+ for d2 = (nth (1+ i) dates)
+ do (let ((gap (round (test-calendar-sync-days-between d1 d2))))
+ (should (= interval gap)))))))))
+
+(ert-deftest test-calendar-sync-property-interval-spacing-weekly-single-day ()
+ "Property: Weekly single-day occurrences are spaced INTERVAL weeks apart."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((interval (1+ (random 3)))
+ (weekday (nth (random 7) '("MO" "TU" "WE" "TH" "FR" "SA" "SU")))
+ (start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (base-event (list :summary "Weekly Interval Test" :start start-date))
+ (rrule (list :freq 'weekly :byday (list weekday) :interval interval :count 8))
+ (range (test-calendar-sync-wide-range))
+ (occurrences (calendar-sync--expand-weekly base-event rrule range)))
+ (when (> (length occurrences) 1)
+ (let ((dates (mapcar (lambda (o) (plist-get o :start)) occurrences)))
+ (cl-loop for i from 0 below (1- (length dates))
+ for d1 = (nth i dates)
+ for d2 = (nth (1+ i) dates)
+ do (let ((gap (round (test-calendar-sync-days-between d1 d2))))
+ (should (= (* 7 interval) gap)))))))))
+
+;;; Property 5: Range Containment
+
+(ert-deftest test-calendar-sync-property-occurrences-within-range ()
+ "Property: All occurrences fall within the date range.
+No occurrence should be before range start or after range end."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((range-start-days (random 30))
+ (range-end-days (+ range-start-days 30 (random 60)))
+ (range (list (time-add (current-time) (* range-start-days 86400))
+ (time-add (current-time) (* range-end-days 86400))))
+ (start-date (test-calendar-sync-time-days-from-now (1+ range-start-days) 10 0))
+ (base-event (list :summary "Range Test" :start start-date))
+ (rrule (list :freq 'daily :interval 1))
+ (occurrences (calendar-sync--expand-daily base-event rrule range)))
+ (dolist (occ occurrences)
+ (let ((occ-start (plist-get occ :start)))
+ (should (calendar-sync--date-in-range-p occ-start range)))))))
+
+(ert-deftest test-calendar-sync-property-weekly-occurrences-within-range ()
+ "Property: All weekly occurrences fall within the date range."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((range (test-calendar-sync-narrow-range))
+ (start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (weekdays (test-calendar-sync-random-weekday-subset))
+ (base-event (list :summary "Range Test" :start start-date))
+ (rrule (list :freq 'weekly :byday weekdays :interval 1))
+ (occurrences (calendar-sync--expand-weekly base-event rrule range)))
+ (dolist (occ occurrences)
+ (let ((occ-start (plist-get occ :start)))
+ (should (calendar-sync--date-in-range-p occ-start range)))))))
+
+;;; Property 6: Determinism
+
+(ert-deftest test-calendar-sync-property-expansion-deterministic-daily ()
+ "Property: Same inputs produce identical outputs for daily expansion."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((interval (1+ (random 3)))
+ (count (+ 5 (random 10)))
+ (start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (base-event (list :summary "Determinism Test" :start start-date))
+ (rrule (list :freq 'daily :interval interval :count count))
+ (range (test-calendar-sync-wide-range))
+ (result1 (calendar-sync--expand-daily base-event rrule range))
+ (result2 (calendar-sync--expand-daily base-event rrule range)))
+ (should (= (length result1) (length result2)))
+ (cl-loop for o1 in result1
+ for o2 in result2
+ do (should (equal (plist-get o1 :start) (plist-get o2 :start)))))))
+
+(ert-deftest test-calendar-sync-property-expansion-deterministic-weekly ()
+ "Property: Same inputs produce identical outputs for weekly expansion."
+ (dotimes (_ test-calendar-sync-property-trials)
+ (let* ((interval (1+ (random 2)))
+ (weekdays (test-calendar-sync-random-weekday-subset))
+ (count (+ 5 (random 10)))
+ (start-date (test-calendar-sync-time-days-from-now 1 10 0))
+ (base-event (list :summary "Determinism Test" :start start-date))
+ (rrule (list :freq 'weekly :byday weekdays :interval interval :count count))
+ (range (test-calendar-sync-wide-range))
+ (result1 (calendar-sync--expand-weekly base-event rrule range))
+ (result2 (calendar-sync--expand-weekly base-event rrule range)))
+ (should (= (length result1) (length result2)))
+ (cl-loop for o1 in result1
+ for o2 in result2
+ do (should (equal (plist-get o1 :start) (plist-get o2 :start)))))))
+
+(provide 'test-calendar-sync-properties)
+;;; test-calendar-sync-properties.el ends here
diff --git a/tests/test-calendar-sync.el b/tests/test-calendar-sync.el
index 2de306b1..7cda5e73 100644
--- a/tests/test-calendar-sync.el
+++ b/tests/test-calendar-sync.el
@@ -452,7 +452,7 @@ Earlier events should appear first in the output."
(ics (test-calendar-sync-make-ics event))
(org-content (calendar-sync--parse-ics ics)))
(should org-content)
- (should (string-match-p "^# Google Calendar Events" org-content))
+ (should (string-match-p "^# Calendar Events" org-content))
(should (string-match-p "\\* Test Event" org-content))))
(ert-deftest test-calendar-sync--parse-ics-normal-multiple-events-all-included ()
@@ -577,7 +577,11 @@ Valid events should be parsed, invalid ones skipped."
(original-offset -21600) ; CST
(original-time (current-time))
(calendar-sync--last-timezone-offset original-offset)
- (calendar-sync--last-sync-time original-time))
+ (calendar-sync--calendar-states (make-hash-table :test 'equal)))
+ ;; Set up per-calendar state
+ (puthash "test-calendar"
+ (list :status 'ok :last-sync original-time :last-error nil)
+ calendar-sync--calendar-states)
(unwind-protect
(progn
;; Save state
@@ -586,14 +590,17 @@ Valid events should be parsed, invalid ones skipped."
;; Clear variables
(setq calendar-sync--last-timezone-offset nil)
- (setq calendar-sync--last-sync-time nil)
+ (clrhash calendar-sync--calendar-states)
;; Load state
(calendar-sync--load-state)
;; Verify loaded correctly
(should (= original-offset calendar-sync--last-timezone-offset))
- (should (equal original-time calendar-sync--last-sync-time)))
+ (let ((loaded-state (gethash "test-calendar" calendar-sync--calendar-states)))
+ (should loaded-state)
+ (should (eq 'ok (plist-get loaded-state :status)))
+ (should (equal original-time (plist-get loaded-state :last-sync)))))
;; Cleanup
(when (file-exists-p test-state-file)
(delete-file test-state-file)))))
@@ -604,7 +611,7 @@ Valid events should be parsed, invalid ones skipped."
(test-state-file (expand-file-name "subdir/state.el" test-dir))
(calendar-sync--state-file test-state-file)
(calendar-sync--last-timezone-offset -21600)
- (calendar-sync--last-sync-time (current-time)))
+ (calendar-sync--calendar-states (make-hash-table :test 'equal)))
(unwind-protect
(progn
(calendar-sync--save-state)
@@ -618,35 +625,79 @@ Valid events should be parsed, invalid ones skipped."
"Test that load-state handles missing file gracefully."
(let ((calendar-sync--state-file "/nonexistent/path/state.el")
(calendar-sync--last-timezone-offset nil)
- (calendar-sync--last-sync-time nil))
+ (calendar-sync--calendar-states (make-hash-table :test 'equal)))
;; Should not error
(should-not (calendar-sync--load-state))
- ;; Variables should remain nil
+ ;; Variables should remain nil/empty
(should-not calendar-sync--last-timezone-offset)
- (should-not calendar-sync--last-sync-time)))
+ (should (= 0 (hash-table-count calendar-sync--calendar-states)))))
(ert-deftest test-calendar-sync--load-state-handles-corrupted-file ()
"Test that load-state handles corrupted state file gracefully."
(let* ((test-state-file (make-temp-file "calendar-sync-test-state"))
(calendar-sync--state-file test-state-file)
(calendar-sync--last-timezone-offset nil)
- (calendar-sync--last-sync-time nil))
+ (calendar-sync--calendar-states (make-hash-table :test 'equal)))
(unwind-protect
(progn
;; Write corrupted data
(with-temp-file test-state-file
(insert "this is not valid elisp {[}"))
- ;; Should handle error gracefully (catches error, logs message)
- ;; Returns error message string, not nil, but doesn't throw
- (should (stringp (calendar-sync--load-state)))
+ ;; Should handle error gracefully (catches error, logs message, returns nil)
+ ;; Function logs to *Messages* but returns nil (doesn't crash)
+ (should-not (calendar-sync--load-state))
- ;; Variables should remain nil (not loaded from corrupted file)
+ ;; Variables should remain nil/empty (not loaded from corrupted file)
(should-not calendar-sync--last-timezone-offset)
- (should-not calendar-sync--last-sync-time))
+ (should (= 0 (hash-table-count calendar-sync--calendar-states))))
;; Cleanup
(when (file-exists-p test-state-file)
(delete-file test-state-file)))))
+;;; Tests: Multi-Calendar Configuration
+
+(ert-deftest test-calendar-sync--calendar-names-returns-names ()
+ "Test that calendar-names returns list of calendar names."
+ (let ((calendar-sync-calendars
+ '((:name "cal1" :url "http://example.com/1" :file "/tmp/cal1.org")
+ (:name "cal2" :url "http://example.com/2" :file "/tmp/cal2.org"))))
+ (should (equal '("cal1" "cal2") (calendar-sync--calendar-names)))))
+
+(ert-deftest test-calendar-sync--calendar-names-empty-when-no-calendars ()
+ "Test that calendar-names returns empty list when no calendars configured."
+ (let ((calendar-sync-calendars nil))
+ (should (null (calendar-sync--calendar-names)))))
+
+(ert-deftest test-calendar-sync--get-calendar-by-name-finds-calendar ()
+ "Test that get-calendar-by-name finds correct calendar."
+ (let ((calendar-sync-calendars
+ '((:name "google" :url "http://google.com" :file "/tmp/gcal.org")
+ (:name "proton" :url "http://proton.me" :file "/tmp/pcal.org"))))
+ (let ((found (calendar-sync--get-calendar-by-name "proton")))
+ (should found)
+ (should (string= "proton" (plist-get found :name)))
+ (should (string= "http://proton.me" (plist-get found :url))))))
+
+(ert-deftest test-calendar-sync--get-calendar-by-name-returns-nil-for-unknown ()
+ "Test that get-calendar-by-name returns nil for unknown calendar."
+ (let ((calendar-sync-calendars
+ '((:name "google" :url "http://google.com" :file "/tmp/gcal.org"))))
+ (should (null (calendar-sync--get-calendar-by-name "nonexistent")))))
+
+(ert-deftest test-calendar-sync--get-calendar-state-returns-nil-for-new ()
+ "Test that get-calendar-state returns nil for calendar without state."
+ (let ((calendar-sync--calendar-states (make-hash-table :test 'equal)))
+ (should (null (calendar-sync--get-calendar-state "new-calendar")))))
+
+(ert-deftest test-calendar-sync--set-and-get-calendar-state ()
+ "Test setting and getting calendar state."
+ (let ((calendar-sync--calendar-states (make-hash-table :test 'equal))
+ (test-state '(:status ok :last-sync (0 0 0) :last-error nil)))
+ (calendar-sync--set-calendar-state "test-cal" test-state)
+ (let ((retrieved (calendar-sync--get-calendar-state "test-cal")))
+ (should retrieved)
+ (should (eq 'ok (plist-get retrieved :status))))))
+
(provide 'test-calendar-sync)
;;; test-calendar-sync.el ends here
diff --git a/tests/test-integration-recurring-events.el b/tests/test-integration-recurring-events.el
index 0d32d9e0..4629e6ef 100644
--- a/tests/test-integration-recurring-events.el
+++ b/tests/test-integration-recurring-events.el
@@ -105,7 +105,7 @@ Validates:
(let ((org-output (calendar-sync--parse-ics test-integration-recurring-events--weekly-ics)))
;; Should generate org-formatted output
(should (stringp org-output))
- (should (string-match-p "^# Google Calendar Events" org-output))
+ (should (string-match-p "^# Calendar Events" org-output))
;; Should contain multiple GTFO entries
(let ((gtfo-count (with-temp-buffer
diff --git a/tests/testutil-calendar-sync.el b/tests/testutil-calendar-sync.el
index c83006b5..d1a94b01 100644
--- a/tests/testutil-calendar-sync.el
+++ b/tests/testutil-calendar-sync.el
@@ -8,6 +8,15 @@
(require 'calendar)
+;;; Test Environment Setup
+
+;; Provide stub for cj/log-silently if not already defined
+;; This function is defined in system-lib.el but tests should run standalone
+(unless (fboundp 'cj/log-silently)
+ (defun cj/log-silently (format-string &rest args)
+ "Stub for testing: silently ignore log messages."
+ nil))
+
;;; Dynamic Timestamp Generation
(defun test-calendar-sync-time-today-at (hour minute)
@@ -48,7 +57,7 @@ Returns (year month day hour minute) list suitable for tests."
(defun test-calendar-sync-time-date-only (offset-days)
"Generate date-only timestamp for OFFSET-DAYS from now.
-Returns (year month day) list for all-day events."
+Returns (year month day) list for all-day events and UNTIL dates."
(let* ((future (time-add (current-time) (* offset-days 24 3600)))
(decoded (decode-time future))
(year (nth 5 decoded))
@@ -56,6 +65,22 @@ Returns (year month day) list for all-day events."
(day (nth 3 decoded)))
(list year month day)))
+(defun test-calendar-sync-time-date-only-ago (offset-days)
+ "Generate date-only timestamp for OFFSET-DAYS ago.
+Returns (year month day) list for UNTIL dates in the past."
+ (let* ((past (time-subtract (current-time) (* offset-days 24 3600)))
+ (decoded (decode-time past))
+ (year (nth 5 decoded))
+ (month (nth 4 decoded))
+ (day (nth 3 decoded)))
+ (list year month day)))
+
+(defun test-calendar-sync-date-only-from-datetime (datetime)
+ "Extract date-only (year month day) from DATETIME list.
+DATETIME is (year month day hour minute).
+Returns (year month day) suitable for UNTIL dates."
+ (list (nth 0 datetime) (nth 1 datetime) (nth 2 datetime)))
+
;;; .ics Test Data Generation
(defun test-calendar-sync-ics-datetime (time-list)
@@ -106,5 +131,68 @@ Each event should be a VEVENT string from `test-calendar-sync-make-vevent'."
(string-join events "\n")
"\nEND:VCALENDAR"))
+;;; Property Test Helpers
+
+(defun test-calendar-sync-random-future-date ()
+ "Generate random date 1-180 days in future with random time.
+Returns (year month day hour minute) list."
+ (test-calendar-sync-time-days-from-now
+ (1+ (random 180))
+ (random 24)
+ (random 60)))
+
+(defun test-calendar-sync-random-past-date ()
+ "Generate random date 1-90 days in past with random time.
+Returns (year month day hour minute) list."
+ (test-calendar-sync-time-days-ago
+ (1+ (random 90))
+ (random 24)
+ (random 60)))
+
+(defun test-calendar-sync-random-weekday-subset ()
+ "Generate random non-empty subset of weekdays.
+Returns list of weekday strings like (\"MO\" \"WE\" \"FR\")."
+ (let ((days '("MO" "TU" "WE" "TH" "FR" "SA" "SU"))
+ (result '()))
+ (dolist (day days)
+ (when (zerop (random 2))
+ (push day result)))
+ ;; Ensure non-empty
+ (or result (list (nth (random 7) days)))))
+
+(defun test-calendar-sync-random-freq ()
+ "Return random RRULE frequency symbol."
+ (nth (random 4) '(daily weekly monthly yearly)))
+
+(defun test-calendar-sync-days-between (date1 date2)
+ "Calculate days between DATE1 and DATE2.
+Both dates are (year month day ...) lists.
+Returns float number of days (positive if date2 > date1)."
+ (let ((t1 (calendar-sync--date-to-time (list (nth 0 date1) (nth 1 date1) (nth 2 date1))))
+ (t2 (calendar-sync--date-to-time (list (nth 0 date2) (nth 1 date2) (nth 2 date2)))))
+ (/ (float-time (time-subtract t2 t1)) 86400.0)))
+
+(defun test-calendar-sync-wide-range ()
+ "Generate wide date range: 90 days past to 365 days future.
+Returns (start-time end-time) suitable for expansion functions."
+ (list (time-subtract (current-time) (* 90 86400))
+ (time-add (current-time) (* 365 86400))))
+
+(defun test-calendar-sync-narrow-range ()
+ "Generate narrow date range: today to 30 days future.
+Returns (start-time end-time) suitable for expansion functions."
+ (list (current-time)
+ (time-add (current-time) (* 30 86400))))
+
+(defun test-calendar-sync-date-to-time-value (date)
+ "Convert DATE list to Emacs time value.
+DATE is (year month day) or (year month day hour minute)."
+ (let ((year (nth 0 date))
+ (month (nth 1 date))
+ (day (nth 2 date))
+ (hour (or (nth 3 date) 0))
+ (minute (or (nth 4 date) 0)))
+ (encode-time 0 minute hour day month year)))
+
(provide 'testutil-calendar-sync)
;;; testutil-calendar-sync.el ends here