@@ -84,6 +84,95 @@ module.exports = function (eleventyConfig) {
8484 return `${ endHourStr } :${ endMinuteStr } ` ;
8585 } ) ;
8686
87+ eleventyConfig . addFilter ( "groupByStartTime" , function ( events ) {
88+ if ( ! Array . isArray ( events ) ) return [ ] ;
89+
90+ const sortedEvents = events . slice ( ) . sort ( ( a , b ) => {
91+ if ( a . start_time < b . start_time ) return - 1 ;
92+ if ( a . start_time > b . start_time ) return 1 ;
93+ return 0 ;
94+ } ) ;
95+
96+ const grouped = [ ] ;
97+ let currentGroup = null ;
98+
99+ for ( const event of sortedEvents ) {
100+ if ( ! currentGroup || currentGroup . start_time !== event . start_time ) {
101+ currentGroup = {
102+ start_time : event . start_time ,
103+ events : [ ]
104+ } ;
105+ grouped . push ( currentGroup ) ;
106+ }
107+ currentGroup . events . push ( event ) ;
108+ }
109+
110+ return grouped ;
111+ } ) ;
112+
113+ eleventyConfig . addFilter ( "groupAndChunkRooms" , function ( roomEntries ) {
114+ const grouped = { } ;
115+
116+ // Step 1: Group by `start`
117+ roomEntries . forEach ( ( [ roomName , sessions ] ) => {
118+ sessions . forEach ( session => {
119+ if ( ! grouped [ session . start ] ) {
120+ grouped [ session . start ] = [ ] ;
121+ }
122+ grouped [ session . start ] . push ( { room : roomName , ...session } ) ;
123+ } ) ;
124+ } ) ;
125+
126+ // Helper: chunk into balanced rows
127+ function chunkBalanced ( arr ) {
128+ const rows = [ ] ;
129+ const n = arr . length ;
130+
131+ if ( n <= 3 ) {
132+ rows . push ( arr ) ;
133+ } else if ( n === 4 ) {
134+ rows . push ( arr . slice ( 0 , 2 ) , arr . slice ( 2 , 4 ) ) ;
135+ } else if ( n === 5 ) {
136+ rows . push ( arr . slice ( 0 , 3 ) , arr . slice ( 3 , 5 ) ) ;
137+ } else if ( n === 7 ) {
138+ rows . push ( arr . slice ( 0 , 2 ) , arr . slice ( 2 , 5 ) , arr . slice ( 5 , 7 ) ) ;
139+ } else {
140+ for ( let i = 0 ; i < n ; i += 3 ) {
141+ rows . push ( arr . slice ( i , i + 3 ) ) ;
142+ }
143+ }
144+
145+ return rows ;
146+ }
147+
148+ // Step 2: Convert groups into { start, rows }
149+ const result = Object . entries ( grouped ) . map ( ( [ start , sessions ] ) => {
150+ return {
151+ start,
152+ rows : chunkBalanced ( sessions )
153+ } ;
154+ } ) ;
155+
156+ // Sort by time (start)
157+ result . sort ( ( a , b ) => a . start . localeCompare ( b . start ) ) ;
158+
159+ return result ;
160+ } ) ;
161+
162+ eleventyConfig . addFilter ( "mobileSorting" , ( items ) => {
163+ if ( ! items || ! Array . isArray ( items ) ) return items ;
164+
165+ return items . slice ( ) . sort ( ( a , b ) => {
166+ if ( a . start_time < b . start_time ) return - 1 ;
167+ if ( a . start_time > b . start_time ) return 1 ;
168+
169+ if ( a . type === "event" && b . type === "fixed" ) return - 1 ;
170+ if ( a . type === "fixed" && b . type === "event" ) return 1 ;
171+
172+ return 0 ;
173+ } ) ;
174+ } ) ;
175+
87176 // rebuild on CSS changes
88177 eleventyConfig . addWatchTarget ( "./src/_includes/css/" ) ;
89178
0 commit comments