summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSacha Chua <sacha@sachachua.com>2026-10-15 13:23:48 -0400
committerSacha Chua <sacha@sachachua.com>2026-10-15 13:23:48 -0400
commitb6b6d024c96663d02c6e0a7061ab76ee47c3bc8c (patch)
tree5febef7f11bc5da669f948a5896ee75cfb2aba4d
parent97b9c64e9584e893f571f3507347e8430c05f649 (diff)
downloademacsconf-wiki-b6b6d024c96663d02c6e0a7061ab76ee47c3bc8c.tar.xz
emacsconf-wiki-b6b6d024c96663d02c6e0a7061ab76ee47c3bc8c.zip
use script.js
-rw-r--r--2026/organizers-notebook.md6
-rw-r--r--2026/organizers-notebook/index.org2
-rw-r--r--script.js39
-rw-r--r--templates/page.tmpl257
4 files changed, 27 insertions, 277 deletions
diff --git a/2026/organizers-notebook.md b/2026/organizers-notebook.md
index d12e40ee..3b03411d 100644
--- a/2026/organizers-notebook.md
+++ b/2026/organizers-notebook.md
@@ -280,7 +280,7 @@ interests you!
## TODO Draft schedule
-Times in this schedule are in America/Toronto, which will be UTC-5.
+Times in this schedule are in America/Toronto, which will be UTC-5. If you have Javascript enabled, you can hover over the entries to see the times translated into your local time.
<svg width="500" height="700" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>Graphical view of the schedule</title><g transform="translate(0,0)"><title>Schedule for Saturday</title><rect width="250" height="700" x="0" y="0" fill="white"></rect><text font-size="10" fill="black" y="30" x="3">Saturday</text><a href="https://emacsconf.org/2026/talks/sat-open" data-start="2026-12-12T14:00:00+0000" data-end="2026-12-12T14:10:00+0000" title="Saturday opening remarks" data-slug="sat-open"><title>Sat 9:00- 9:10 Saturday opening remarks</title><rect x="40" y="40" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="5,5,5" fill="gray"></rect><g transform="translate(40,51)"><text fill="black" x="0" y="0" font-size="10" transform="nil">sat-open</text></g></a><a href="https://emacsconf.org/2026/talks/planning" data-start="2026-12-12T14:10:00+0000" data-end="2026-12-12T14:30:00+0000" title="The Emacs Planning Habits of a Questionably Effective Person: My 40-year journey of planning with Emacs, Org Mode, paper journals, etc." data-slug="planning"><title>Sat 9:10- 9:30 The Emacs Planning Habits of a Questionably Effective Person: My 40-year journey of planning with Emacs, Org Mode, paper journals, etc.</title><rect x="40" y="53" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(40,78)"><text fill="black" x="0" y="0" font-size="10" transform="nil">planning</text></g></a><a href="https://emacsconf.org/2026/talks/listen" data-start="2026-12-12T14:50:00+0000" data-end="2026-12-12T15:10:00+0000" title="Controlling Emacs by voice using Emacslisten" data-slug="listen"><title>Sat 9:50-10:10 Controlling Emacs by voice using Emacslisten</title><rect x="40" y="108" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(40,133)"><text fill="black" x="0" y="0" font-size="10" transform="nil">listen</text></g></a><a href="https://emacsconf.org/2026/talks/emacspeak" data-start="2026-12-12T15:30:00+0000" data-end="2026-12-12T16:00:00+0000" title="Multi-dimensional information processing with Emacs and Emacspeak: a blind man's perspective" data-slug="emacspeak"><title>Sat 10:30-11:00 Multi-dimensional information processing with Emacs and Emacspeak: a blind man's perspective</title><rect x="40" y="163" opacity="0.8" width="84" height="41" stroke="black" stroke-dasharray="5,5,5" fill="gray"></rect><g transform="translate(40,202)"><text fill="black" x="0" y="0" font-size="10" transform="nil">emacspeak</text></g></a><a href="https://emacsconf.org/2026/talks/ltx-talk" data-start="2026-12-12T16:10:00+0000" data-end="2026-12-12T16:30:00+0000" title="ltx-talk: Accessible presentations with ox-beamer" data-slug="ltx-talk"><title>Sat 11:10-11:30 ltx-talk: Accessible presentations with ox-beamer</title><rect x="40" y="218" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,243)"><text fill="black" x="0" y="0" font-size="10" transform="nil">ltx-talk</text></g></a><a href="https://emacsconf.org/2026/talks/plots" data-start="2026-12-12T18:00:00+0000" data-end="2026-12-12T18:20:00+0000" title="Plots with ROOTs: Resilient data visualization with Emacs, Org and gnuplot" data-slug="plots"><title>Sat 1:00- 1:20 Plots with ROOTs: Resilient data visualization with Emacs, Org and gnuplot</title><rect x="40" y="369" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(40,394)"><text fill="black" x="0" y="0" font-size="10" transform="nil">plots</text></g></a><a href="https://emacsconf.org/2026/talks/ffs" data-start="2026-12-12T18:40:00+0000" data-end="2026-12-12T19:00:00+0000" title="Plain text presentations in GNU Emacs with ffs" data-slug="ffs"><title>Sat 1:40- 2:00 Plain text presentations in GNU Emacs with ffs</title><rect x="40" y="424" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,449)"><text fill="black" x="0" y="0" font-size="10" transform="nil">ffs</text></g></a><a href="https://emacsconf.org/2026/talks/mobile" data-start="2026-12-12T19:20:00+0000" data-end="2026-12-12T19:30:00+0000" title="How I solved Org Mode's biggest mobile and collaboration problems" data-slug="mobile"><title>Sat 2:20- 2:30 How I solved Org Mode's biggest mobile and collaboration problems</title><rect x="40" y="479" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,490)"><text fill="black" x="0" y="0" font-size="10" transform="nil">mobile</text></g></a><a href="https://emacsconf.org/2026/talks/hyperbole" data-start="2026-12-12T19:50:00+0000" data-end="2026-12-12T20:10:00+0000" title="Hyperbole, My Dear Watson" data-slug="hyperbole"><title>Sat 2:50- 3:10 Hyperbole, My Dear Watson</title><rect x="40" y="520" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,545)"><text fill="black" x="0" y="0" font-size="10" transform="nil">hyperbole</text></g></a><a href="https://emacsconf.org/2026/talks/koutliner" data-start="2026-12-12T20:30:00+0000" data-end="2026-12-12T20:50:00+0000" title="Hyperbole Koutliner: The Best Autonumbered, Hyperlinking Outliner for Emacs" data-slug="koutliner"><title>Sat 3:30- 3:50 Hyperbole Koutliner: The Best Autonumbered, Hyperlinking Outliner for Emacs</title><rect x="40" y="575" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,600)"><text fill="black" x="0" y="0" font-size="10" transform="nil">koutliner</text></g></a><a href="https://emacsconf.org/2026/talks/writing" data-start="2026-12-12T21:10:00+0000" data-end="2026-12-12T21:30:00+0000" title="Close the writing accountability gap with Emacs" data-slug="writing"><title>Sat 4:10- 4:30 Close the writing accountability gap with Emacs</title><rect x="40" y="630" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,655)"><text fill="black" x="0" y="0" font-size="10" transform="nil">writing</text></g></a><a href="https://emacsconf.org/2026/talks/sat-close" data-start="2026-12-12T21:50:00+0000" data-end="2026-12-12T22:00:00+0000" title="Saturday closing remarks / open session" data-slug="sat-close"><title>Sat 4:50- 5:00 Saturday closing remarks / open session</title><rect x="40" y="685" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,696)"><text fill="black" x="0" y="0" font-size="10" transform="nil">sat-close</text></g></a><a href="https://emacsconf.org/2026/talks/community" data-start="2026-12-12T15:30:00+0000" data-end="2026-12-12T16:30:00+0000" title="Community brainstorming" data-slug="community"><title>Sat 10:30-11:30 Community brainstorming</title><rect x="125" y="163" opacity="0.8" width="84" height="82" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(125,243)"><text fill="black" x="0" y="0" font-size="10" transform="nil">community</text></g></a><a href="https://emacsconf.org/2026/talks/portable" data-start="2026-12-12T18:00:00+0000" data-end="2026-12-12T18:15:00+0000" title="Emacs as my portable user space across operating platforms" data-slug="portable"><title>Sat 1:00- 1:15 Emacs as my portable user space across operating platforms</title><rect x="125" y="369" opacity="0.8" width="84" height="20" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(125,387)"><text fill="black" x="0" y="0" font-size="10" transform="nil">portable</text></g></a><a href="https://emacsconf.org/2026/talks/os" data-start="2026-12-12T18:35:00+0000" data-end="2026-12-12T18:55:00+0000" title="Emacs everywhere: A fun romp through esoteric operating systems" data-slug="os"><title>Sat 1:35- 1:55 Emacs everywhere: A fun romp through esoteric operating systems</title><rect x="125" y="417" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(125,442)"><text fill="black" x="0" y="0" font-size="10" transform="nil">os</text></g></a><a href="https://emacsconf.org/2026/talks/cadet" data-start="2026-12-12T19:15:00+0000" data-end="2026-12-12T19:25:00+0000" title="My Space Cadet Deck - an Android Stream Deck replacement with deep Emacs integration" data-slug="cadet"><title>Sat 2:15- 2:25 My Space Cadet Deck - an Android Stream Deck replacement with deep Emacs integration</title><rect x="125" y="472" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(125,483)"><text fill="black" x="0" y="0" font-size="10" transform="nil">cadet</text></g></a><a href="https://emacsconf.org/2026/talks/remoto" data-start="2026-12-12T19:45:00+0000" data-end="2026-12-12T20:05:00+0000" title="El Remoto: browse any GitHub repos without cloning them" data-slug="remoto"><title>Sat 2:45- 3:05 El Remoto: browse any GitHub repos without cloning them</title><rect x="125" y="513" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(125,538)"><text fill="black" x="0" y="0" font-size="10" transform="nil">remoto</text></g></a><g transform="translate(3,40)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T14:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">9 AM</text></g><g transform="translate(3,122)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T15:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">10 AM</text></g><g transform="translate(3,204)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T16:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">11 AM</text></g><g transform="translate(3,287)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T17:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">12 PM</text></g><g transform="translate(3,369)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T18:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">1 PM</text></g><g transform="translate(3,451)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T19:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">2 PM</text></g><g transform="translate(3,534)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T20:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">3 PM</text></g><g transform="translate(3,616)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T21:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">4 PM</text></g><g transform="translate(3,698)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-12T22:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">5 PM</text></g></g><g transform="translate(250,0)"><title>Schedule for Sunday</title><rect width="250" height="700" x="0" y="0" fill="white"></rect><text font-size="10" fill="black" y="30" x="3">Sunday</text><a href="https://emacsconf.org/2026/talks/sun-open" data-start="2026-12-13T14:00:00+0000" data-end="2026-12-13T14:10:00+0000" title="Sunday opening remarks" data-slug="sun-open"><title>Sun 9:00- 9:10 Sunday opening remarks</title><rect x="40" y="40" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="5,5,5" fill="gray"></rect><g transform="translate(40,51)"><text fill="black" x="0" y="0" font-size="10" transform="nil">sun-open</text></g></a><a href="https://emacsconf.org/2026/talks/bone" data-start="2026-12-13T14:10:00+0000" data-end="2026-12-13T14:20:00+0000" title="BONE and gnaw.el: tracking what matters" data-slug="bone"><title>Sun 9:10- 9:20 BONE and gnaw.el: tracking what matters</title><rect x="40" y="53" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(40,64)"><text fill="black" x="0" y="0" font-size="10" transform="nil">bone</text></g></a><a href="https://emacsconf.org/2026/talks/local" data-start="2026-12-13T14:40:00+0000" data-end="2026-12-13T14:50:00+0000" title="Local file history possibilities in Emacs" data-slug="local"><title>Sun 9:40- 9:50 Local file history possibilities in Emacs</title><rect x="40" y="94" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(40,105)"><text fill="black" x="0" y="0" font-size="10" transform="nil">local</text></g></a><a href="https://emacsconf.org/2026/talks/hutch" data-start="2026-12-13T15:10:00+0000" data-end="2026-12-13T15:20:00+0000" title="hutch: code reviews for the mildly disenfranchised" data-slug="hutch"><title>Sun 10:10-10:20 hutch: code reviews for the mildly disenfranchised</title><rect x="40" y="136" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="5,5,5" fill="lightblue"></rect><g transform="translate(40,147)"><text fill="black" x="0" y="0" font-size="10" transform="nil">hutch</text></g></a><a href="https://emacsconf.org/2026/talks/team" data-start="2026-12-13T15:30:00+0000" data-end="2026-12-13T15:50:00+0000" title="Beyond the Chatbot: Team-Oriented AI in Emacs" data-slug="team"><title>Sun 10:30-10:50 Beyond the Chatbot: Team-Oriented AI in Emacs</title><rect x="40" y="163" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,188)"><text fill="black" x="0" y="0" font-size="10" transform="nil">team</text></g></a><a href="https://emacsconf.org/2026/talks/compile" data-start="2026-12-13T16:10:00+0000" data-end="2026-12-13T16:30:00+0000" title="Beyond shell history: Saving compilation output in Emacs" data-slug="compile"><title>Sun 11:10-11:30 Beyond shell history: Saving compilation output in Emacs</title><rect x="40" y="218" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,243)"><text fill="black" x="0" y="0" font-size="10" transform="nil">compile</text></g></a><a href="https://emacsconf.org/2026/talks/dnd" data-start="2026-12-13T18:00:00+0000" data-end="2026-12-13T18:10:00+0000" title="DnD and Org Roam: Becoming a Better DM with Emacs" data-slug="dnd"><title>Sun 1:00- 1:10 DnD and Org Roam: Becoming a Better DM with Emacs</title><rect x="40" y="369" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect><g transform="translate(40,380)"><text fill="black" x="0" y="0" font-size="10" transform="nil">dnd</text></g></a><a href="https://emacsconf.org/2026/talks/bible" data-start="2026-12-13T18:20:00+0000" data-end="2026-12-13T18:40:00+0000" title="bible-gateway: A Two-Edged Sword in Emacs" data-slug="bible"><title>Sun 1:20- 1:40 bible-gateway: A Two-Edged Sword in Emacs</title><rect x="40" y="396" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,421)"><text fill="black" x="0" y="0" font-size="10" transform="nil">bible</text></g></a><a href="https://emacsconf.org/2026/talks/svg" data-start="2026-12-13T19:00:00+0000" data-end="2026-12-13T19:20:00+0000" title="A (sort of) REPL for learning SVG" data-slug="svg"><title>Sun 2:00- 2:20 A (sort of) REPL for learning SVG</title><rect x="40" y="451" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,476)"><text fill="black" x="0" y="0" font-size="10" transform="nil">svg</text></g></a><a href="https://emacsconf.org/2026/talks/align" data-start="2026-12-13T19:40:00+0000" data-end="2026-12-13T20:00:00+0000" title="Column-aligning text in Emacs" data-slug="align"><title>Sun 2:40- 3:00 Column-aligning text in Emacs</title><rect x="40" y="506" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,531)"><text fill="black" x="0" y="0" font-size="10" transform="nil">align</text></g></a><a href="https://emacsconf.org/2026/talks/anju" data-start="2026-12-13T20:20:00+0000" data-end="2026-12-13T20:40:00+0000" title="Revisiting Emacs Mouse Interactions with Anju" data-slug="anju"><title>Sun 3:20- 3:40 Revisiting Emacs Mouse Interactions with Anju</title><rect x="40" y="561" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect><g transform="translate(40,586)"><text fill="black" x="0" y="0" font-size="10" transform="nil">anju</text></g></a><a href="https://emacsconf.org/2026/talks/ghostel" data-start="2026-12-13T20:50:00+0000" data-end="2026-12-13T21:10:00+0000" title="Ghost in the Shell: a libghostty powered terminal for Emacs" data-slug="ghostel"><title>Sun 3:50- 4:10 Ghost in the Shell: a libghostty powered terminal for Emacs</title><rect x="40" y="602" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="peachpuff"></rect><g transform="translate(40,627)"><text fill="black" x="0" y="0" font-size="10" transform="nil">ghostel</text></g></a><a href="https://emacsconf.org/2026/talks/sun-close" data-start="2026-12-13T21:30:00+0000" data-end="2026-12-13T21:40:00+0000" title="Sunday closing remarks" data-slug="sun-close"><title>Sun 4:30- 4:40 Sunday closing remarks</title><rect x="40" y="657" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(40,668)"><text fill="black" x="0" y="0" font-size="10" transform="nil">sun-close</text></g></a><a href="https://emacsconf.org/2026/talks/prefix" data-start="2026-12-13T15:00:00+0000" data-end="2026-12-13T15:10:00+0000" title="prefix-tab-groups" data-slug="prefix"><title>Sun 10:00-10:10 prefix-tab-groups</title><rect x="125" y="122" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect><g transform="translate(125,133)"><text fill="black" x="0" y="0" font-size="10" transform="nil">prefix</text></g></a><a href="https://emacsconf.org/2026/talks/rau" data-start="2026-12-13T15:20:00+0000" data-end="2026-12-13T15:40:00+0000" title="Emacs as a Window Manager and concurrency" data-slug="rau"><title>Sun 10:20-10:40 Emacs as a Window Manager and concurrency</title><rect x="125" y="149" opacity="0.8" width="84" height="27" stroke="black" stroke-dasharray="" fill="lightblue"></rect><g transform="translate(125,174)"><text fill="black" x="0" y="0" font-size="10" transform="nil">rau</text></g></a><a href="https://emacsconf.org/2026/talks/babel" data-start="2026-12-13T16:00:00+0000" data-end="2026-12-13T16:10:00+0000" title="Org Babel everywhere" data-slug="babel"><title>Sun 11:00-11:10 Org Babel everywhere</title><rect x="125" y="204" opacity="0.8" width="84" height="13" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(125,215)"><text fill="black" x="0" y="0" font-size="10" transform="nil">babel</text></g></a><a href="https://emacsconf.org/2026/talks/llms" data-start="2026-12-13T18:00:00+0000" data-end="2026-12-13T19:00:00+0000" title="Meetup/panel about LLMs?" data-slug="llms"><title>Sun 1:00- 2:00 Meetup/panel about LLMs?</title><rect x="125" y="369" opacity="0.8" width="84" height="82" stroke="black" stroke-dasharray="" fill="gray"></rect><g transform="translate(125,449)"><text fill="black" x="0" y="0" font-size="10" transform="nil">llms</text></g></a><g transform="translate(3,40)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T14:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">9 AM</text></g><g transform="translate(3,122)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T15:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">10 AM</text></g><g transform="translate(3,204)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T16:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">11 AM</text></g><g transform="translate(3,287)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T17:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">12 PM</text></g><g transform="translate(3,369)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T18:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">1 PM</text></g><g transform="translate(3,451)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T19:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">2 PM</text></g><g transform="translate(3,534)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T20:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">3 PM</text></g><g transform="translate(3,616)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T21:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">4 PM</text></g><g transform="translate(3,698)"><line stroke="darkgray" x1="40" y1="0" x2="210" y2="0"></line><text data-start="2026-12-13T22:00:00+0000" fill="black" x="0" y="0" font-size="10" dy=".4em">5 PM</text></g></g></svg>
@@ -623,7 +623,7 @@ AM: 9-12 PM EST, PM: 1-5 PM EST (plus a little extra for setup/transition)
Saturday Dec 12 2026
-<table id="org6179353">
+<table id="orgcea1aca">
<colgroup>
@@ -675,7 +675,7 @@ Saturday Dec 12 2026
Sunday Dec 13 2026
-<table id="org36cf717">
+<table id="org7178d01">
<colgroup>
diff --git a/2026/organizers-notebook/index.org b/2026/organizers-notebook/index.org
index 21e51c29..d89a34ba 100644
--- a/2026/organizers-notebook/index.org
+++ b/2026/organizers-notebook/index.org
@@ -206,7 +206,7 @@ CLOSED: [2026-07-02 Thu 11:35]
:CUSTOM_ID: draft-schedule
:END:
-Times in this schedule are in America/Toronto, which will be UTC-5.
+Times in this schedule are in America/Toronto, which will be UTC-5. If you have Javascript enabled, you can hover over the entries to see the times translated into your local time.
#+NAME: schedule
#+begin_src emacs-lisp :results value replace :exports none :eval never-export :var filename="schedule.svg"
diff --git a/script.js b/script.js
index c127d3a9..9777c060 100644
--- a/script.js
+++ b/script.js
@@ -1,8 +1,8 @@
-// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0-or-later
+ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0-or-later
/*
SeekToTime - simple script to add video time jump functionality to timestamp links
- Copyright (C) 2020 Grant Shangreaux
+ Copyright (C) 2020-2024 Grant Shangreaux and Sacha Chua
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@@ -36,16 +36,21 @@
function handleSubtitleClick(event) {
var video = event.target.getAttribute('data-video');
- var start = event.target.getAttribute('data-start');
- var videoElem = document.getElementById(video);
- if (videoElem) {
- videoElem.currentTime = parseSeconds(start);
- videoElem.scrollIntoView();
- }
- if (event.preventDefault) {
- event.preventDefault();
- }
- }
+ var start = event.target.getAttribute('data-start');
+ const stickyVideo = document.querySelector('.transcript #' + video);
+ const indexCardVideo = document.querySelector('.vid #' + video);
+ if (indexCardVideo) {
+ indexCardVideo.currentTime = parseSeconds(start);
+ }
+ if (stickyVideo && window.getComputedStyle(stickyVideo).display == 'block') {
+ stickyVideo.currentTime = parseSeconds(start);
+ } else {
+ indexCardVideo.scrollIntoView();
+ }
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
+ }
window.onload = function initScript() {
let subtitles = document.getElementsByClassName('subtitle');
@@ -53,11 +58,11 @@
subtitles[i].onclick = handleSubtitleClick;
}
}
-// @license-end
+ // @license-end
// @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
-// Copyright (C) 2021, 2022 Sacha Chua
+ // Copyright (C) 2021, 2022, 2026 Sacha Chua
-function addLocalTimeToSVGs() {
+ function addLocalTimeToSVGs() {
var dateOptions = {
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric',
@@ -122,7 +127,7 @@ addLocalTimeToSVGs();
}
}
-// @license-end
+ // @license-end
// @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
// Copyright (c) 2021 Sacha Chua - CC0 Public Domain
function displayChapters(elem) {
@@ -207,7 +212,7 @@ addLocalTimeToSVGs();
if (transcriptDiv.querySelector('.vid'))
transcriptDiv.querySelector('.vid').remove();
// already has it
- // TODO: Make a copy of the video and place it at the start of the btranscript div, positioned to the left, and sticky, but only on large screens.
+ // TODO: Make a copy of the video and place it at the start of the transcript div, positioned to the left, and sticky, but only on large screens.
const videoCopy = video.cloneNode(true);
transcriptDiv.prepend(videoCopy);
videoCopy.classList.add('sticky-video');
diff --git a/templates/page.tmpl b/templates/page.tmpl
index 85d94a42..cb845818 100644
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -36,70 +36,6 @@
</TMPL_IF>
</TMPL_LOOP>
</TMPL_UNLESS>
-
-<script>
- // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0-or-later
- /*
-
- SeekToTime - simple script to add video time jump functionality to timestamp links
- Copyright (C) 2020-2024 Grant Shangreaux and Sacha Chua
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-
- This script enables wiki editors to create anchor tags with the class "time-link"
- that will be parsed for seeking to specific time stamps in the main video on a page.
- The tag should look like this:
-
- <a href="#mainVideo" class="time-link">mm:ss</a>
-
- This could be extended to accept hours in the time stamp as well, but currently does not.
- */
- let timestamps;
-
- // expects a string like "mm:ss.mmm"
- function parseSeconds(timeString) {
- return timeString.split(":").reduce(function(prev, o) {
- return prev * 60 + parseFloat(o);
- }, 0);
- }
-
- function handleSubtitleClick(event) {
- var video = event.target.getAttribute('data-video');
- var start = event.target.getAttribute('data-start');
- const stickyVideo = document.querySelector('.transcript #' + video);
- const indexCardVideo = document.querySelector('.vid #' + video);
- if (indexCardVideo) {
- indexCardVideo.currentTime = parseSeconds(start);
- }
- if (stickyVideo && window.getComputedStyle(stickyVideo).display == 'block') {
- stickyVideo.currentTime = parseSeconds(start);
- } else {
- indexCardVideo.scrollIntoView();
- }
- if (event.preventDefault) {
- event.preventDefault();
- }
- }
-
- window.onload = function initScript() {
- let subtitles = document.getElementsByClassName('subtitle');
- for (let i = 0; i < subtitles.length; i++) {
- subtitles[i].onclick = handleSubtitleClick;
- }
- }
- // @license-end
-</script>
</head>
<body <TMPL_IF SIDEBAR>class="has-sidebar"</TMPL_IF>>
@@ -285,197 +221,6 @@ Last edited <TMPL_VAR MTIME>
<TMPL_IF HTML5></footer><TMPL_ELSE></div></TMPL_IF>
<TMPL_IF HTML5></article><TMPL_ELSE></div></TMPL_IF>
-
-<script>
- // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
- // Copyright (C) 2021, 2022, 2026 Sacha Chua
-
- function addLocalTimeToSVGs() {
- var dateOptions = {
- year: 'numeric', month: 'numeric', day: 'numeric',
- hour: 'numeric', minute: 'numeric',
- timeZoneName: 'short' };
- document.querySelectorAll('svg a[data-start]').forEach((o) => {
- let start = new Date(o.getAttribute('data-start'));
- let title = o.querySelector('title');
- if (title) {
- title.textContent += ' = ' + start.toLocaleString([], dateOptions);
- }
- });
-}
-
-addLocalTimeToSVGs();
-
- if (document.querySelector('.times')) {
- var dateOptions = {dateStyle: 'short', timeStyle: 'short'};
- var localStart = (new Date(document.querySelector('.times').getAttribute('start'))).toLocaleString([], dateOptions);
- var localEnd = (new Date(document.querySelector('.times').getAttribute('end'))).toLocaleString([], dateOptions);
- var dateElem = document.createElement('div');
- dateElem.appendChild(document.createTextNode('Your local time: ~ ' + localStart + ' to ~ ' + localEnd));
- document.querySelector('.times').prepend(dateElem);
- if (document.querySelector('.times').querySelector('.others')) {
- document.querySelector('.times').querySelector('.others').style.display = 'none';
- }
- }
- if (document.querySelector('.time-overlay')) {
- document.querySelectorAll('.time-overlay').forEach(function (o) {
- if (o.getAttribute('title')) return;
- var dateOptions = {dateStyle: 'short', timeStyle: 'short'};
- var localStart, localEnd;
- if (o.getAttribute('start') && o.getAttribute('end')) {
- localStart = (new Date(o.getAttribute('start'))).toLocaleString([], dateOptions);
- localEnd = (new Date(o.getAttribute('end'))).toLocaleString([], dateOptions);
- o.setAttribute('title', 'Your local time: ~ ' + localStart + ' to ~ ' + localEnd);
- } else if (o.getAttribute('start')) {
- localStart = (new Date(o.getAttribute('start'))).toLocaleString([], dateOptions);
- o.setAttribute('title', 'Your local time: ~ ' + localStart);
- }
- });
- }
-
- if (document.querySelector('a[name=transcript]')) {
- var transcriptLink = document.createElement('a');
- transcriptLink.setAttribute('href', '#transcript');
- transcriptLink.textContent = 'View transcript';
- var video = document.querySelector('.mainVideo video');
- if (video) {
- var resources = document.querySelector('.mainVideo video').closest('.vid').querySelector('.resources');
- var transcriptDiv = document.createElement('div');
- transcriptDiv.appendChild(transcriptLink)
- if (resources) { resources.prepend(transcriptDiv); }
- }
- }
- var chat = document.querySelector('.chat-iframe');
- if (chat) {
- if (chat.getAttribute('data-track')) {
- chat.innerHTML = '<iframe src="https://chat.emacsconf.org?join=emacsconf,emacsconf-' +
- chat.getAttribute('data-track').replace(/[^A-Za-z]/g, '') + '" height="600" width="100%"></iframe>';
- } else {
- chat.innerHTML = '<iframe src="https://chat.emacsconf.org" height="600" width="100%"></iframe>';
- }
- }
-
- // @license-end
-</script>
-<script>
- // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
- // Copyright (c) 2021 Sacha Chua - CC0 Public Domain
- function displayChapters(elem) {
- var i;
- var chapter;
- var list = document.createElement('ol');
- list.setAttribute('class', 'chapters');
- var link;
- var target = elem.getAttribute('data-target');
- var video = document.getElementById(target);
- var track;
- if (video) {
- track = video.addTextTrack('chapters');
- track.mode = 'hidden';
- }
- var chapters = elem.textContent.split(/[ \t]*\n+[ \t]*/).forEach(function(line) {
- var m = (line.match(/^(((?:[0-9]+:)?[0-9]+:[0-9]+)(?:\.[0-9]+))[ \t]+(.*)/));
- if (m) {
- var start = m[1];
- var text = m[3];
- chapter = document.createElement('li');
- link = document.createElement('a');
- link.setAttribute('href', '#');
- link.setAttribute('data-video', target);
- link.setAttribute('data-start', start);
- link.setAttribute('data-start-s', parseSeconds(start));
- link.appendChild(document.createTextNode(m[2] + ' ' + text));
- link.onclick = handleSubtitleClick;
- chapter.appendChild(link);
- list.appendChild(chapter);
- if (track) {
- var time = parseSeconds(start);
- if (track.cues.length > 0) {
- track.cues[track.cues.length - 1].endTime = time - 1;
- }
- track.addCue(new VTTCue(time, time, text));
- }
- }
- })
- if (track && track.cues.length > 0) {
- video.addEventListener('durationchange', function() {
- track.cues[track.cues.length - 1].endTime = video.duration;
- });
- track.addEventListener('cuechange', function() {
- if (!this.activeCues[0]) return;
- if (list.querySelector('.current')) {
- list.querySelector('.current').className = '';
- }
- var chapter;
- if (chapter = list.querySelector('a[data-start-s="' + this.activeCues[0].startTime + '"]')) {
- chapter.parentNode.className = 'current';
- }
- });
- }
- elem.parentNode.replaceChild(list, elem);
- }
-
- document.querySelectorAll('pre.chapters').forEach(displayChapters);
-
- var video = document.querySelector('video.reload');
- if (video) {
- var myVar = setInterval(reloadAsNeeded, 1000);
- var oldTime = '';
- function reloadAsNeeded() {
- if ((video.paused != true && (video.currentTime - oldTime) == 0 && video.currentTime != 0)) {
- var source = video.querySelector('source');
- var oldVideo = source.src;
- source.src = '';
- source.src = oldVideo;
- video.load();
- video.play();
- }
- oldTime = video.currentTime;
- };
- }
-
- /* videoType: mainVideo, qanda */
- function addStickyVideo(videoType) {
- const transcriptDiv = document.querySelector('.transcript-' + videoType);
- const video = document.querySelector('.vid.' + videoType + ' video');
- if (!video || !transcriptDiv) return;
- if (transcriptDiv.querySelector('.vid'))
- transcriptDiv.querySelector('.vid').remove();
- // already has it
- // TODO: Make a copy of the video and place it at the start of the transcript div, positioned to the left, and sticky, but only on large screens.
- const videoCopy = video.cloneNode(true);
- transcriptDiv.prepend(videoCopy);
- videoCopy.classList.add('sticky-video');
- // TODO: fix the ID
-
- }
-
-
-
- // @license-end
- // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt txt CC0-1.0
- // Copyright (c) 2023 Sacha Chua - CC0 Public Domain
- function highlightTalks() {
- // highlight any talk mentioned in the highlight URL parameter
- var params = new URLSearchParams(window.location.search);
- if (!params.get('highlight')) return;
- var talks = params.get('highlight').split(',').filter(function(o) { return o.match(/^[-a-z0-9]+$/); });
- var regexp = new RegExp('/talks/(' + talks.join('|') + ')/?$');
- document.querySelectorAll('a[href]').forEach(function(link) {
- console.debug(link.getAttribute('href'), link.getAttribute('href').match(regexp));
- if (link.getAttribute('href').match(regexp)) {
- console.debug(link);
- link.classList.add('highlight');
- }
- });
- }
-
- addEventListener('DOMContentLoaded', highlightTalks);
- addEventListener('DOMContentLoaded', function() {
- addStickyVideo('mainVideo');
- addStickyVideo('qanda');
- });
- // @license-end
-</script>
+<script src="https://emacsconf.org/script.js"></script>
</body>
</html>