From 6d670d069efddddce0a211ca5d9f1ae3a3d7a287 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 29 Aug 2025 17:42:49 +0200 Subject: SoundDevices 8-series support! --- README.md | 1 + build.bat | 3 +- main.odin | 232 ++++++++++++++++++++++++++++++++++++--------- test/290825_25Y08M27_1.CSV | 108 +++++++++++++++++++++ test/290825_25Y08M28_1.CSV | 47 +++++++++ 5 files changed, 346 insertions(+), 45 deletions(-) create mode 100644 test/290825_25Y08M27_1.CSV create mode 100644 test/290825_25Y08M28_1.CSV diff --git a/README.md b/README.md index 4115c5e..2bb83a6 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Turns the awkward CSVs into a beautiful self-contained HTML file. ## Tested on reports from: +- Sound Devices 888 (v11.00) - Sound Devices 688 - Zoom F8n Pro diff --git a/build.bat b/build.bat index b413d1b..f847c6e 100755 --- a/build.bat +++ b/build.bat @@ -1,2 +1,3 @@ -odin run . -debug -pdb-name:bin/better-report.pdb -out:bin/better-report.exe -- test +odin build . -debug -pdb-name:bin/better-report.pdb -out:bin/better-report.exe +bin\better-report.exe test\ odin build . -o:speed -out:C:/tools/better-report.exe \ No newline at end of file diff --git a/main.odin b/main.odin index c5f3125..cd3d3c5 100755 --- a/main.odin +++ b/main.odin @@ -8,11 +8,13 @@ import "core:sys/windows" import "core:strings" /* -TODO: Drag-n-drop window -TODO: Testing with 8-series +TODO: Simplify pre-allocation. Just allocate a bunch. It's probably fine. + Maybe do it by just counting how many lines are longer than 2 characters. +TODO: Drag-n-drop window if no files are specified */ VERBOSE :: false +INCLUDE_DATE :: false // By default I delete the retarded date field that says what day the report was generated. PART_ONE :: #load("parts/start.html", string) PART_TWO :: #load("parts/start2.html", string) @@ -22,6 +24,7 @@ Device :: enum { UNSET, ZOOM, SD6, + SD8, // Tested with 888 } Stages :: enum { @@ -123,20 +126,25 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { // STAGE 1 -------------------------------------------------------------- // First, we detect what kind of sound report this is - for line, line_number in lines { + for line, line_number in lines[:3] { if (device!=.UNSET) { break } - if line == "\"SOUND REPORT\"," { + if line == "\"SOUND REPORT\"," { device = .ZOOM if VERBOSE do fmt.printf("Detected ZOOM from quotes and comma on line index {}\n", line_number) } - if line == "\"ZOOM F8\"," { + if line == "\"ZOOM F8\"," { device = .ZOOM if VERBOSE do fmt.printf("Detected ZOOM from \"ZOOM F8\" on line index {}\n", line_number) } - if line == "SOUND REPORT" { + if line == "SOUND REPORT" { device = .SD6 if VERBOSE do fmt.printf("Detected SOUND_DEVICES from unquoted SOUND REPORT line index {}\n", line_number) } + if len(line)<15 do continue + if line[:13] == "SOUND REPORT," { + device = .SD8 + if VERBOSE do fmt.printf("Detected SOUND_DEVICES 8-series from SOUND REPORT with missing newline on line index {}\n", line_number) + } } if device == .UNSET { @@ -148,44 +156,76 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { // STAGE 2 -------------------------------------------------------------- // Measuring content for allocation - if device == .ZOOM { - output.column_count = 21 // Ugly magic number, could be fucked by firmware update - - // Padded for expanding info lines from unchanging columns - output.info_lines = make([]Info_Line, 2+output.column_count, context.temp_allocator) - output.info_line_count = 2 + + switch device { + case .ZOOM: + output.column_count = 21 // Ugly magic number, could be fucked by firmware update + + // Padded for expanding info lines from unchanging columns + output.info_lines = make([]Info_Line, 2+output.column_count, context.temp_allocator) + output.info_line_count = 2 + + output.row_count = strings.count(string(data), "\n") - 7 // Ugly magic number, could be fucked by firmware update + output.table = make([][]string, output.row_count, context.temp_allocator) + output.header = make([]string, output.column_count, context.temp_allocator) + for &row in output.table { + row = make([]string, output.column_count, context.temp_allocator) + } + case .SD6: + second_to_last_line := lines[len(lines)-2] + output.column_count = strings.count(second_to_last_line, ",") + count_stage : Stages = .TITLE + for line, l in lines { + switch count_stage { + case .TITLE: + if l == 1 { // Ugly magic number, could be fucked by firmware update + count_stage = .INFO + } + case .INFO: + if line == "," { + count_stage = .HEADER + continue + } else if len(line) > 2 { + output.info_line_count += 1 + } + case .HEADER: + if line == "" { + count_stage = .BODY + } + case .BODY: + if len(line)>2 { + output.row_count += 1 + } + } + } + output.info_lines = make([]Info_Line, output.info_line_count+output.column_count, context.temp_allocator) + output.header = make([]string, output.column_count, context.temp_allocator) + output.table = make([][]string, output.row_count, context.temp_allocator) + for &row in output.table { + row = make([]string, output.column_count, context.temp_allocator) + } - output.row_count = strings.count(string(data), "\n") - 7 // Ugly magic number, could be fucked by firmware update - output.table = make([][]string, output.row_count, context.temp_allocator) - output.header = make([]string, output.column_count, context.temp_allocator) - for &row in output.table { - row = make([]string, output.column_count, context.temp_allocator) - } - } else if device == .SD6 { - second_to_last_line := lines[len(lines)-2] - output.column_count = strings.count(second_to_last_line, ",") - count_stage : Stages = .TITLE - for line, l in lines { - switch count_stage { - case .TITLE: - if l == 1 { // Ugly magic number, could be fucked by firmware update - count_stage = .INFO - } - case .INFO: - if line == "," { - count_stage = .HEADER - continue - } else if len(line) > 2 { - output.info_line_count += 1 - } - case .HEADER: - if line == "" { - count_stage = .BODY - } - case .BODY: - if len(line)>2 { - output.row_count += 1 - } + case .SD8: + count_stage : Stages = .INFO + for line, l in lines { + #partial switch count_stage { + case .INFO: + if line == "," { + count_stage = .HEADER + continue + } else if len(line) > 2 { + output.info_line_count += 1 + } + case .HEADER: + if len(line) > 2 { + // Missing comma at the en in 8-series report, v therefore + 1 + output.column_count = strings.count(line, ",") + 1 + count_stage = .BODY + } + case .BODY: + if len(line)>2 { + output.row_count += 1 + } } } output.info_lines = make([]Info_Line, output.info_line_count+output.column_count, context.temp_allocator) @@ -194,10 +234,12 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { for &row in output.table { row = make([]string, output.column_count, context.temp_allocator) } + + case .UNSET: + unreachable() } - // STAGE 3 -------------------------------------------------------------- // Filling with data @@ -208,6 +250,107 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { stage : Stages = .TITLE #partial switch device { + case .SD8: + // .d8888b. 8888888b. .d8888b. + // d88P Y88b 888 "Y88b d88P Y88b + // Y88b. 888 888 Y88b. d88P + // "Y888b. 888 888 "Y88888" + // "Y88b. 888 888 .d8P""Y8b. + // "888 888 888 888 888 + // Y88b d88P 888 .d88P Y88b d88P + // "Y8888P" 8888888P" "Y8888P" + fmt.printf("Parsing [{}] as Sound Devices 8XX report, ", file_info.name) + if strings.contains(file_info.name, "_1.CSV") || strings.contains(file_info.name, "_2.CSV") { + output.title = file_info.name[7:len(file_info.name)-6] + } else { + output.title = file_info.name + } + fmt.printf("titled \"{}\".\n", output.title) + + info_line_index := 0 + body_line_index := 0 + for line, line_index in lines { + switch stage { + case .TITLE: + // Missing newline on 8-series means we get info on the title line + stage = .INFO + + line_elements := strings.split(line, ",") + if VERBOSE do fmt.printf(".INFO {}: {}\n", line_index, line_elements) + field := fmt.aprintf("{}:", line_elements[1], allocator=context.temp_allocator) + entry := line_elements[2] + output.info_lines[info_line_index].field = field + output.info_lines[info_line_index].entry = entry + info_line_index += 1 + + + case .INFO: + if line == "," { + stage = .HEADER + continue + } + line_elements := strings.split(line, ",") + if VERBOSE do fmt.printf(".INFO {}: {}\n", line_index, line_elements) + if line_elements[0] == "Date" { + if VERBOSE do fmt.printf("Skipping line {}, because it's the retarded date field on an 8-series\n", line_index) + output.info_line_count -= 1 + continue + } + field := fmt.aprintf("{}:", line_elements[0], allocator=context.temp_allocator) + entry := line_elements[1] + output.info_lines[info_line_index].field = field + output.info_lines[info_line_index].entry = entry + info_line_index += 1 + + + case .HEADER: + if line == "," { + continue // This is here because there are a bunch of lines that are just commas before the header + } else if len(line)>3 { + if VERBOSE do fmt.printf(".HEADER {}:", line_index) + // No trailing comma in the header?? + for element, e in strings.split(line, ",") { + if VERBOSE do fmt.printf(" {}", element) + + output.header[e] = element + if element[:3] == "Trk" { + if first_channel_index == -1 do first_channel_index = e + last_channel_index = e + output.header[e] = fmt.aprintf("Trk {}", e-first_channel_index+1, allocator=context.temp_allocator) + } + if element == "Start TC" { + output.tc_column_index = e + } + } + + if VERBOSE do fmt.printf("\n") + if VERBOSE do fmt.printf("first_channel_index: {}\n", first_channel_index) + if VERBOSE do fmt.printf("last_channel_index: {}\n", last_channel_index) + stage = .BODY + } + + + case .BODY: + if len(line) > 2 { + if VERBOSE do fmt.printf(".BODY {}:", line_index) + for element, e in strings.split(line, ",") { + if VERBOSE do fmt.printf(" {}", element) + entry : string = element + output.table[body_line_index][e] = entry + } + if VERBOSE do fmt.printf("\n") + body_line_index += 1 + } + + + } + } + + fmt.printf("\n") + + + + case .SD6: // .d8888b. 8888888b. .d8888b. // d88P Y88b 888 "Y88b d88P Y88b @@ -262,6 +405,7 @@ parse :: proc(path : string, device : Device = .UNSET) -> (Report, bool) { if element[:4] == "Trk " { if first_channel_index == -1 do first_channel_index = e last_channel_index = e + // TODO: Rename track column with corrected numbers } if element == "Start TC" { output.tc_column_index = e diff --git a/test/290825_25Y08M27_1.CSV b/test/290825_25Y08M27_1.CSV new file mode 100644 index 0000000..4fc1974 --- /dev/null +++ b/test/290825_25Y08M27_1.CSV @@ -0,0 +1,108 @@ +SOUND REPORT,Roll,25Y08M27 +Date,29/08/25 +Sound Mixer,San Jacobs +Phone,(+1) 234 567 8900 +E-Mail,san@example.org +File Type (SSD),Poly(ISO) +File Type (SD1),Poly(ISO) +File Type (SD2),Poly(ISO) +Sample Rate,48000Hz +Frame Rate,25 +Bit Depth,24-bits +Tone Level,0 dBFS +, +, +File Name,Scene,Take,Length,Start TC,Trk3,Trk4,Trk5,Trk6,Notes +SL02T01,SL02,01,00:01:19,10:17:32:00,BOOM,JESPER,OLA,LAERERINNE,Total klasserom +SL02T02,SL02,02,00:01:41,10:19:23:00,BOOM,JESPER,OLA,LAERERINNE, +SL02T03,SL02,03,00:01:01,10:21:07:00,BOOM,JESPER,OLA,LAERERINNE, +SL02T04,SL02,04,00:00:41,10:22:39:00,BOOM,JESPER,OLA,LAERERINNE, +SL02T05,SL02,05,00:00:28,10:23:40:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T01,SL03,01,00:00:49,10:27:46:00,BOOM,JESPER,OLA,LAERERINNE,m.close laererinne +SL03T02,SL03,02,00:00:40,10:29:32:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T03,SL03,03,00:00:25,10:30:34:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T04,SL03,04,00:01:01,10:31:14:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T05,SL03,05,00:01:01,10:32:15:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T06,SL03,06,00:00:45,10:33:43:00,BOOM,JESPER,OLA,LAERERINNE, +SL03T07,SL03,07,00:00:39,10:35:28:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T01,SL04,01,00:00:41,10:51:06:00,BOOM,JESPER,OLA,LAERERINNE,Jesper reveal bonde +SL04T02,SL04,02,00:00:23,10:51:47:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T03,SL04,03,00:00:44,10:53:50:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T04,SL04,04,00:00:56,10:55:10:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T05,SL04,05,00:00:57,10:56:23:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T06,SL04,06,00:00:31,10:57:20:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T07,SL04,07,00:00:34,10:57:56:00,BOOM,JESPER,OLA,LAERERINNE, +SL04T08,SL04,08,00:00:59,10:59:23:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T01,SL05,01,00:01:27,11:16:07:00,BOOM,JESPER,OLA,LAERERINNE,toskudd rapp +SL05T02,SL05,02,00:01:04,11:20:06:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T03,SL05,03,00:00:48,11:21:10:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T04,SL05,04,00:00:52,11:21:58:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T05,SL05,05,00:01:06,11:24:47:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T06,SL05,06,00:00:53,11:25:53:00,BOOM,JESPER,OLA,LAERERINNE, +SL05T07,SL05,07,00:00:48,11:28:12:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T01,SL06,01,00:00:34,11:38:52:00,BOOM,JESPER,OLA,LAERERINNE,jesper rapp +SL06T02,SL06,02,00:00:58,11:39:52:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T03,SL06,03,00:00:40,11:41:14:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T04,SL06,04,00:00:46,11:41:54:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T05,SL06,05,00:01:20,11:42:57:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T06,SL06,06,00:01:16,11:44:17:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T07,SL06,07,00:01:02,11:45:51:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T08,SL06,08,00:01:31,11:46:53:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T09,SL06,09,00:00:34,11:49:24:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T10,SL06,10,00:00:40,11:54:10:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T11,SL06,11,00:03:30,11:54:50:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T12,SL06,12,00:01:18,11:58:26:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T13,SL06,13,00:00:28,11:59:44:00,BOOM,JESPER,OLA,LAERERINNE, +SL06T14,SL06,14,00:00:44,12:00:12:00,BOOM,JESPER,OLA,LAERERINNE, +SL08T01,SL08,01,00:01:12,12:03:41:00,BOOM,JESPER,OLA,LAERERINNE, +SL09T01,SL09,01,00:00:38,12:14:10:00,BOOM,JESPER,OLA,LAERERINNE, +SL09T02,SL09,02,00:01:31,12:16:21:00,BOOM,JESPER,OLA,LAERERINNE, +SL09T03,SL09,03,00:01:22,12:17:54:00,BOOM,JESPER,OLA,LAERERINNE, +SL09T04,SL09,04,00:02:45,12:19:32:00,BOOM,JESPER,OLA,LAERERINNE, +SL10T01,SL10,01,00:03:08,12:22:30:00,BOOM,JESPER,OLA,LAERERINNE,kidsa digger +SL10T02,SL10,02,00:01:26,12:27:27:00,BOOM,JESPER,OLA,LAERERINNE, +SL10T03,SL10,03,00:00:11,12:30:13:00,BOOM,JESPER,OLA,LAERERINNE, +SL11T01,SL11,01,00:00:59,12:45:00:00,BOOM,JESPER,OLA,LAERERINNE, +SL11T02,SL11,02,00:01:34,12:45:59:00,BOOM,JESPER,OLA,LAERERINNE, +SL12T01,SL12,01,00:01:15,13:29:31:00,BOOM,JESPER,OLA,LAERERINNE, +SL13T01,SL13,01,00:08:15,13:55:15:00,BOOM,JESPER,OLA,LAERERINNE,Jesper og Ola b-walker unna +SL14T01,SL14,01,00:02:28,14:53:38:00,BOOM,JESPER,OLA,LAERERINNE, +SL14T02,SL14,02,00:00:18,14:56:43:00,BOOM,JESPER,OLA,LAERERINNE, +SL14T03,SL14,03,00:01:23,14:58:00:00,BOOM,JESPER,OLA,LAERERINNE, +SL14T04,SL14,04,00:01:16,15:00:09:00,BOOM,JESPER,OLA,LAERERINNE, +SL14T05,SL14,05,00:00:08,15:10:26:00,BOOM,JESPER,OLA,LAERERINNE, +SL15T01,SL15,01,00:01:17,15:13:14:00,BOOM,JESPER,OLA,LAERERINNE,Hvilken rase e kyllingen? Fremmed Rase? +SL15T02,SL15,02,00:01:22,15:15:03:00,BOOM,JESPER,OLA,LAERERINNE,Hvilken rase e kyllingen? Fremmed Rase? +SL15T03,SL15,03,00:00:37,15:16:25:00,BOOM,JESPER,OLA,LAERERINNE,Hvilken rase e kyllingen? Fremmed Rase? +SL15T04,SL15,04,00:00:44,15:17:19:00,BOOM,JESPER,OLA,LAERERINNE,Hvilken rase e kyllingen? Fremmed Rase? +SL15T05,SL15,05,00:00:36,15:18:40:00,BOOM,JESPER,OLA,LAERERINNE,Hvilken rase e kyllingen? Fremmed Rase? +SL16T01,SL16,01,00:01:31,15:45:16:00,BOOM,JESPER,OLA,LAERERINNE, +SL16T02,SL16,02,00:03:09,15:47:04:00,BOOM,JESPER,OLA,LAERERINNE, +SL16T03,SL16,03,00:00:45,15:54:24:00,BOOM,JESPER,OLA,LAERERINNE, +SL16T04,SL16,04,00:00:30,15:55:09:00,BOOM,JESPER,OLA,LAERERINNE, +SL16T05,SL16,05,00:00:26,15:57:13:00,BOOM,JESPER,OLA,LAERERINNE, +SL16T05A,SL16,05,00:00:34,15:57:39:00,BOOM,JESPER,OLA,, +SL16T06,SL16,06,00:00:44,15:58:22:00,BOOM,JESPER,OLA,, +SL16T07,SL16,07,00:00:24,15:59:06:00,BOOM,JESPER,OLA,, +SL16T08,SL16,08,00:00:48,16:00:16:00,BOOM,JESPER,OLA,, +SL16T09,SL16,09,00:00:26,16:01:04:00,BOOM,JESPER,OLA,, +SL16T10,SL16,10,00:00:35,16:01:40:00,BOOM,JESPER,OLA,, +SL16T11,SL16,11,00:00:22,16:02:15:00,BOOM,JESPER,OLA,, +SL17T01,SL17,01,00:00:38,16:04:16:00,BOOM,JESPER,OLA,,WILD: Dem spise når dem vil å bare chille når det blir natt +SL18T01,SL18,01,00:00:53,16:07:53:00,BOOM,JESPER,OLA,, +SL18T02,SL18,02,00:00:57,16:09:04:00,BOOM,JESPER,OLA,, +SL19T01,SL19,01,00:00:27,16:13:53:00,BOOM,JESPER,OLA,,Ola plukker i close +SL19T02,SL19,02,00:00:29,16:14:52:00,BOOM,JESPER,OLA,, +SL19T03,SL19,03,00:01:07,16:15:44:00,BOOM,JESPER,OLA,, +SL20T01,SL20,01,00:00:40,16:34:59:00,BOOM,JESPER,OLA,,love oeving +SL20T02,SL20,02,00:00:53,16:37:34:00,BOOM,JESPER,OLA,, +SL20T03,SL20,03,00:00:43,16:40:22:00,BOOM,JESPER,OLA,, +SL21T01,SL21,01,00:00:40,16:43:19:00,BOOM,JESPER,OLA,,E kyllingan gla i fotball +SL21T02,SL21,02,00:00:43,16:45:03:00,BOOM,JESPER,OLA,, +SL21T03,SL21,03,00:00:34,16:46:07:00,BOOM,JESPER,OLA,, +SL22T01,SL22,01,00:00:38,16:55:27:00,BOOM,JESPER,OLA,, +SL23T01,SL23,01,00:01:18,16:57:25:00,BOOM,JESPER,OLA,,Musikk forran laaven +SL23T02,SL23,02,00:00:36,16:59:02:00,BOOM,JESPER,OLA,, +SL23T03,SL23,03,00:00:57,17:00:20:00,BOOM,JESPER,OLA,, +SL24T01,SL24,01,00:00:43,17:03:18:00,BOOM,JESPER,OLA,,Jesper sitt bilde med ball +SL24T02,SL24,02,00:00:26,17:04:01:00,BOOM,JESPER,OLA,,Jesper sitt bilde med ball diff --git a/test/290825_25Y08M28_1.CSV b/test/290825_25Y08M28_1.CSV new file mode 100644 index 0000000..de9ceec --- /dev/null +++ b/test/290825_25Y08M28_1.CSV @@ -0,0 +1,47 @@ +SOUND REPORT,Roll,25Y08M28 +Date,29/08/25 +Sound Mixer,San Jacobs +Phone,(+1) 234 567 8900 +E-Mail,san@example.org +File Type (SSD),Poly(ISO) +File Type (SD1),Poly(ISO) +File Type (SD2),Poly(ISO) +Sample Rate,48000Hz +Frame Rate,25 +Bit Depth,24-bits +Tone Level,0 dBFS +, +, +File Name,Scene,Take,Length,Start TC,Trk3,Trk4,Trk5,Notes +SL25T01,SL25,01,00:10:55,08:49:27:00,BOOM,JESPER,OLA,False +SL25T02,SL25,02,00:01:49,09:15:50:00,,JESPER,OLA,Plass? dem har masse. lys? sann passe +SL25T03,SL25,03,00:00:57,09:17:39:00,,JESPER,OLA, +SL25T04,SL25,04,00:00:54,09:18:52:00,,JESPER,OLA, +SL25T05,SL25,05,00:00:57,09:20:37:00,,JESPER,OLA, +SL25T06,SL25,06,00:02:07,09:22:07:00,,JESPER,OLA, +SL26T01,SL26,01,00:01:01,09:32:46:00,,JESPER,OLA, +SL26T02,SL26,02,00:01:10,09:35:04:00,,JESPER,OLA, +SL26T03,SL26,03,00:00:33,09:37:39:00,,JESPER,OLA, +SL26T04,SL26,04,00:00:34,09:40:00:00,,JESPER,OLA, +SL26T05,SL26,05,00:00:36,09:41:14:00,,JESPER,OLA, +SL26T06,SL26,06,00:00:47,09:43:00:00,,JESPER,OLA, +SL27T01,SL27,01,00:00:37,09:48:03:00,,JESPER,OLA, +SL27T02,SL27,02,00:01:26,09:49:00:00,,JESPER,OLA, +SL27T03,SL27,03,00:00:41,09:50:46:00,,JESPER,OLA, +SL27T04,SL27,04,00:02:01,09:54:51:00,,JESPER,OLA, +SL27T05,SL27,05,00:04:49,09:57:38:00,,JESPER,OLA, +SL27T06,SL27,06,00:01:34,10:04:53:00,,JESPER,OLA, +SL27T07,SL27,07,00:01:38,10:06:43:00,,JESPER,OLA, +SL28T01,SL28,01,00:02:04,10:18:42:00,,JESPER,OLA, +SL28T02,SL28,02,00:00:21,10:20:46:00,,JESPER,OLA, +SL28T03,SL28,03,00:00:28,10:23:53:00,,JESPER,OLA, +SL28T04,SL28,04,00:02:49,10:25:07:00,,JESPER,OLA, +SL29T01,SL29,01,00:01:01,10:33:49:00,,JESPER,OLA, +SL29T02,SL29,02,00:00:50,10:34:57:00,,JESPER,OLA, +SL29T03,SL29,03,00:03:01,11:05:13:00,,JESPER,OLA, +SL29T04,SL29,04,00:02:18,11:08:14:00,,JESPER,OLA, +SL31T01,SL31,01,00:00:28,11:51:41:00,BOOM,JESPER,OLA,Jesper ser inn vindu ext +SL31T02,SL31,02,00:01:41,11:52:20:00,BOOM,JESPER,OLA, +SL32T01,SL32,01,00:00:22,11:54:22:00,BOOM,JESPER,OLA,Jesper ser inn vindu ext +SL32T02,SL32,02,00:01:00,11:54:48:00,BOOM,JESPER,OLA, +SL33T01,SL33,01,00:01:17,12:49:12:00,BOOM,JESPER,OLA,Plass? Lys? Ola og Jesper tar på fjoesdrakt -- cgit v1.2.1