Compare commits

...

10 Commits

15 changed files with 2949 additions and 169 deletions

1601
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,654 @@
[]
[
{
"title": "Scores",
"parent_dir": "images",
"media": "1_Scores",
"order": "1",
"images": [
{
"title": "Handwritten Score for 'Paris' (1972)",
"details": "Page 1",
"media": "1_Handwritten Score for 'Paris' (1972)_Page 1.png",
"thumb": "1_Handwritten Score for 'Paris' (1972)_Page 1.thumb.png"
},
{
"title": "Handwritten Score for 'Paris' (1972)",
"details": "Page 2",
"media": "2_Handwritten Score for 'Paris' (1972)_Page 2.png",
"thumb": "2_Handwritten Score for 'Paris' (1972)_Page 2.thumb.png"
},
{
"title": "Handwritten Score for 'Paris' (1972)",
"details": "Page 3",
"media": "3_Handwritten Score for 'Paris' (1972)_Page 3.png",
"thumb": "3_Handwritten Score for 'Paris' (1972)_Page 3.thumb.png"
},
{
"title": "Handwritten Score for 'Paris' (1972)",
"details": "Page 4",
"media": "4_Handwritten Score for 'Paris' (1972)_Page 4.png",
"thumb": "4_Handwritten Score for 'Paris' (1972)_Page 4.thumb.png"
}
]
},
{
"title": "Watercolors - Untitled Studies (1970-1986)",
"parent_dir": "images",
"media": "2_Watercolors - Untitled Studies (1970-1986)",
"order": "2",
"images": [
{
"title": "Study 1",
"details": "Series of Watercolors",
"media": "1_Study 1_Series of Watercolors.jpg",
"thumb": "1_Study 1_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 2",
"details": "Series of Watercolors",
"media": "2_Study 2_Series of Watercolors.jpg",
"thumb": "2_Study 2_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 3",
"details": "Series of Watercolors",
"media": "3_Study 3_Series of Watercolors.jpg",
"thumb": "3_Study 3_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 4",
"details": "Series of Watercolors",
"media": "4_Study 4_Series of Watercolors.jpg",
"thumb": "4_Study 4_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 5",
"details": "Series of Watercolors",
"media": "5_Study 5_Series of Watercolors.jpg",
"thumb": "5_Study 5_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 6",
"details": "Series of Watercolors",
"media": "6_Study 6_Series of Watercolors.jpg",
"thumb": "6_Study 6_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 7",
"details": "Series of Watercolors",
"media": "7_Study 7_Series of Watercolors.jpg",
"thumb": "7_Study 7_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 8",
"details": "Series of Watercolors",
"media": "8_Study 8_Series of Watercolors.jpg",
"thumb": "8_Study 8_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 9",
"details": "Series of Watercolors",
"media": "9_Study 9_Series of Watercolors.jpg",
"thumb": "9_Study 9_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 10",
"details": "Series of Watercolors",
"media": "10_Study 10_Series of Watercolors.jpg",
"thumb": "10_Study 10_Series of Watercolors.thumb.jpg"
},
{
"title": "Study 11",
"details": "Series of Watercolors",
"media": "11_Study 11_Series of Watercolors.jpg",
"thumb": "11_Study 11_Series of Watercolors.thumb.jpg"
}
]
},
{
"title": "Posters",
"parent_dir": "images",
"media": "3_Posters",
"order": "3",
"images": [
{
"title": "Vessel: an opera epic (1971)",
"details": "site-specific locations, NYC, October 1971 Design/drawing by Meredith Monk with print by Monica Moseley",
"media": "6_Vessel: an opera epic (1971)_site-specific locations, NYC, October 1971 Design/drawing by Meredith Monk with print by Monica Moseley.jpg",
"thumb": "6_Vessel: an opera epic (1971)_site-specific locations, NYC, October 1971 Design/drawing by Meredith Monk with print by Monica Moseley.thumb.jpg"
},
{
"title": "Quarry: an opera in three movements (1976)",
"details": "La MaMa Annex, NYC, April 1976 Design/drawing by Meredith Monk with print by Monica Moseley",
"media": "1_Quarry: an opera in three movements (1976)_La MaMa Annex, NYC, April 1976 Design/drawing by Meredith Monk with print by Monica Moseley.jpg",
"thumb": "1_Quarry: an opera in three movements (1976)_La MaMa Annex, NYC, April 1976 Design/drawing by Meredith Monk with print by Monica Moseley.thumb.jpg"
},
{
"title": "Songs from the Hill and Tablet (1976)",
"details": "Town Hall, NYC, October 1976, Design/Drawing by Meredith Monk with print by Monica Moseley",
"media": "5_Songs from the Hill and Tablet (1976)_Town Hall, NYC, October 1976, Design/Drawing by Meredith Monk with print by Monica Moseley.jpg",
"thumb": "5_Songs from the Hill and Tablet (1976)_Town Hall, NYC, October 1976, Design/Drawing by Meredith Monk with print by Monica Moseley.thumb.jpg"
},
{
"title": "The Games: a science fiction opera (1983)",
"details": "Schaubühne am Lehniner Platz, Berlin, Germany Designed by Meredith Monk, Ping Chong and Yoshio Yabara",
"media": "2_The Games: a science fiction opera (1983)_Schaubühne am Lehniner Platz, Berlin, Germany Designed by Meredith Monk, Ping Chong and Yoshio Yabara.jpg",
"thumb": "2_The Games: a science fiction opera (1983)_Schaubühne am Lehniner Platz, Berlin, Germany Designed by Meredith Monk, Ping Chong and Yoshio Yabara.thumb.jpg"
},
{
"title": "ATLAS: an opera in three parts (1991)",
"details": "World premiere flyer 1991",
"media": "3_ATLAS: an opera in three parts (1991)_World premiere flyer 1991.png",
"thumb": "3_ATLAS: an opera in three parts (1991)_World premiere flyer 1991.thumb.png"
},
{
"title": "mercy (2002)",
"details": "Brooklyn Academy of Music (BAM), New York, December 2002",
"media": "4_mercy (2002)_Brooklyn Academy of Music (BAM), New York, December 2002.jpg",
"thumb": "4_mercy (2002)_Brooklyn Academy of Music (BAM), New York, December 2002.thumb.jpg"
}
]
},
{
"title": "Map",
"parent_dir": "images",
"media": "4_Map",
"order": "4",
"images": [
{
"title": "impermanence (2008)",
"details": "Special edition print",
"media": "1_impermanence (2008)_Special edition print.jpg",
"thumb": "1_impermanence (2008)_Special edition print.thumb.jpg"
}
]
},
{
"title": "Indra's Net - Scores and Music Fragments",
"parent_dir": "images",
"media": "5_Indra's Net - Scores and Music Fragments",
"order": "5",
"images": [
{
"title": "Melody themes 1 (2019)",
"media": "59_Melody themes 1 (2019).png",
"thumb": "59_Melody themes 1 (2019).thumb.png"
},
{
"title": "Melody themes 3-6 (2019)",
"media": "60_Melody themes 3-6 (2019).png",
"thumb": "60_Melody themes 3-6 (2019).thumb.png"
},
{
"title": "Melody themes 5 (2019)",
"media": "61_Melody themes 5 (2019).png",
"thumb": "61_Melody themes 5 (2019).thumb.png"
},
{
"title": "Melody themes 6 continued (2019)",
"media": "62_Melody themes 6 continued (2019).png",
"thumb": "62_Melody themes 6 continued (2019).thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page 01",
"media": "01_"Anthem" full score (2023)_Page 01.png",
"thumb": "01_"Anthem" full score (2023)_Page 01.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page 02",
"media": "02_"Anthem" full score (2023)_Page 02.png",
"thumb": "02_"Anthem" full score (2023)_Page 02.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page 03",
"media": "03_"Anthem" full score (2023)_ Page 03.png",
"thumb": "03_"Anthem" full score (2023)_ Page 03.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_04",
"media": "04_"Anthem" full score (2023)_Page_04.png",
"thumb": "04_"Anthem" full score (2023)_Page_04.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_05",
"media": "05_"Anthem" full score (2023)_Page_05.png",
"thumb": "05_"Anthem" full score (2023)_Page_05.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_06",
"media": "06_"Anthem" full score (2023)_Page_06.png",
"thumb": "06_"Anthem" full score (2023)_Page_06.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_07",
"media": "07_"Anthem" full score (2023)_Page_07.png",
"thumb": "07_"Anthem" full score (2023)_Page_07.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_08",
"media": "08_"Anthem" full score (2023)_Page_08.png",
"thumb": "08_"Anthem" full score (2023)_Page_08.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_09",
"media": "09_"Anthem" full score (2023)_Page_09.png",
"thumb": "09_"Anthem" full score (2023)_Page_09.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_10",
"media": "10_"Anthem" full score (2023)_Page_10.png",
"thumb": "10_"Anthem" full score (2023)_Page_10.thumb.png"
},
{
"title": " "Anthem" full score (2023)",
"details": "Page_11",
"media": "11_ "Anthem" full score (2023)_Page_11.png",
"thumb": "11_ "Anthem" full score (2023)_Page_11.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_12",
"media": "12_"Anthem" full score (2023)_Page_12.png",
"thumb": "12_"Anthem" full score (2023)_Page_12.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_13",
"media": "13_"Anthem" full score (2023)_Page_13.png",
"thumb": "13_"Anthem" full score (2023)_Page_13.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_14",
"media": "14_"Anthem" full score (2023)_Page_14.png",
"thumb": "14_"Anthem" full score (2023)_Page_14.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_15",
"media": "15_"Anthem" full score (2023)_Page_15.png",
"thumb": "15_"Anthem" full score (2023)_Page_15.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_16",
"media": "16_"Anthem" full score (2023)_Page_16.png",
"thumb": "16_"Anthem" full score (2023)_Page_16.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_17",
"media": "17_"Anthem" full score (2023)_Page_17.png",
"thumb": "17_"Anthem" full score (2023)_Page_17.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_18",
"media": "18_"Anthem" full score (2023)_Page_18.png",
"thumb": "18_"Anthem" full score (2023)_Page_18.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_19",
"media": "19_"Anthem" full score (2023)_Page_19.png",
"thumb": "19_"Anthem" full score (2023)_Page_19.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_20",
"media": "20_"Anthem" full score (2023)_Page_20.png",
"thumb": "20_"Anthem" full score (2023)_Page_20.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_21",
"media": "21_"Anthem" full score (2023)_Page_21.png",
"thumb": "21_"Anthem" full score (2023)_Page_21.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_22",
"media": "22_"Anthem" full score (2023)_Page_22.png",
"thumb": "22_"Anthem" full score (2023)_Page_22.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_23",
"media": "23_"Anthem" full score (2023)_Page_23.png",
"thumb": "23_"Anthem" full score (2023)_Page_23.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_24",
"media": "24_"Anthem" full score (2023)_Page_24.png",
"thumb": "24_"Anthem" full score (2023)_Page_24.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_25",
"media": "25_"Anthem" full score (2023)_Page_25.png",
"thumb": "25_"Anthem" full score (2023)_Page_25.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_26",
"media": "26_"Anthem" full score (2023)_Page_26.png",
"thumb": "26_"Anthem" full score (2023)_Page_26.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_27",
"media": "27_"Anthem" full score (2023)_Page_27.png",
"thumb": "27_"Anthem" full score (2023)_Page_27.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_28",
"media": "28_"Anthem" full score (2023)_Page_28.png",
"thumb": "28_"Anthem" full score (2023)_Page_28.thumb.png"
},
{
"title": ""Anthem" full score (2023)",
"details": "Page_29",
"media": "29_"Anthem" full score (2023)_Page_29.png",
"thumb": "29_"Anthem" full score (2023)_Page_29.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_01",
"media": "30_/Rotation/ full score (2023)_Page_01.png",
"thumb": "30_/Rotation/ full score (2023)_Page_01.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_02",
"media": "31_/Rotation/ full score (2023)_Page_02.png",
"thumb": "31_/Rotation/ full score (2023)_Page_02.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_03",
"media": "32_/Rotation/ full score (2023)_Page_03.png",
"thumb": "32_/Rotation/ full score (2023)_Page_03.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_04",
"media": "33_/Rotation/ full score (2023)_Page_04.png",
"thumb": "33_/Rotation/ full score (2023)_Page_04.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_05",
"media": "34_/Rotation/ full score (2023)_Page_05.png",
"thumb": "34_/Rotation/ full score (2023)_Page_05.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_06",
"media": "35_/Rotation/ full score (2023)_Page_06.png",
"thumb": "35_/Rotation/ full score (2023)_Page_06.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_07",
"media": "36_/Rotation/ full score (2023)_Page_07.png",
"thumb": "36_/Rotation/ full score (2023)_Page_07.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_08",
"media": "37_/Rotation/ full score (2023)_Page_08.png",
"thumb": "37_/Rotation/ full score (2023)_Page_08.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_09",
"media": "38_/Rotation/ full score (2023)_Page_09.png",
"thumb": "38_/Rotation/ full score (2023)_Page_09.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_10",
"media": "39_/Rotation/ full score (2023)_Page_10.png",
"thumb": "39_/Rotation/ full score (2023)_Page_10.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_11",
"media": "40_/Rotation/ full score (2023)_Page_11.png",
"thumb": "40_/Rotation/ full score (2023)_Page_11.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_12",
"media": "41_/Rotation/ full score (2023)_Page_12.png",
"thumb": "41_/Rotation/ full score (2023)_Page_12.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_13",
"media": "42_/Rotation/ full score (2023)_Page_13.png",
"thumb": "42_/Rotation/ full score (2023)_Page_13.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_14",
"media": "43_/Rotation/ full score (2023)_Page_14.png",
"thumb": "43_/Rotation/ full score (2023)_Page_14.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_15",
"media": "44_/Rotation/ full score (2023)_Page_15.png",
"thumb": "44_/Rotation/ full score (2023)_Page_15.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_16",
"media": "45_/Rotation/ full score (2023)_Page_16.png",
"thumb": "45_/Rotation/ full score (2023)_Page_16.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_17",
"media": "46_/Rotation/ full score (2023)_Page_17.png",
"thumb": "46_/Rotation/ full score (2023)_Page_17.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_18",
"media": "47_/Rotation/ full score (2023)_Page_18.png",
"thumb": "47_/Rotation/ full score (2023)_Page_18.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_19",
"media": "48_/Rotation/ full score (2023)_Page_19.png",
"thumb": "48_/Rotation/ full score (2023)_Page_19.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_20",
"media": "49_/Rotation/ full score (2023)_Page_20.png",
"thumb": "49_/Rotation/ full score (2023)_Page_20.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_21",
"media": "50_/Rotation/ full score (2023)_Page_21.png",
"thumb": "50_/Rotation/ full score (2023)_Page_21.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_22",
"media": "51_/Rotation/ full score (2023)_Page_22.png",
"thumb": "51_/Rotation/ full score (2023)_Page_22.thumb.png"
},
{
"title": ""Rotation" full score (2023)",
"details": "Page_23",
"media": "52_/Rotation/ full score (2023)_Page_23.png",
"thumb": "52_/Rotation/ full score (2023)_Page_23.thumb.png"
},
{
"title": "Chord structure for the beginning of "Rotation" (2013)",
"media": "53_Chord structure for the beginning of /Rotation/ (2013).jpg",
"thumb": "53_Chord structure for the beginning of /Rotation/ (2013).thumb.jpg"
},
{
"title": ""Jewels" sections music material (2013)",
"media": "54_/Jewels/ sections music material (2013).jpg",
"thumb": "54_/Jewels/ sections music material (2013).thumb.jpg"
},
{
"title": "&#34Jewel 2&#34 and &#34Jewel 4&#34 (2019)",
"media": "55_&#47Jewel 2&#47 and &#47Jewel 4&#47 (2019).png",
"thumb": "55_&#47Jewel 2&#47 and &#47Jewel 4&#47 (2019).thumb.png"
},
{
"title": "&#34Jewel 3&#34 (2019)",
"media": "56_&#47Jewel 3&#47 (2019).png",
"thumb": "56_&#47Jewel 3&#47 (2019).thumb.png"
},
{
"title": "&#34Jewel 5&#34 and &#34Jewel 4&#34 (2017-2019)",
"media": "57_&#47Jewel 5&#47 and &#47Jewel 4&#47 (2017-2019).png",
"thumb": "57_&#47Jewel 5&#47 and &#47Jewel 4&#47 (2017-2019).thumb.png"
},
{
"title": "&#34Jewel 5&#34 with syllables (2021)",
"media": "58_&#47Jewel 5&#47 with syllables (2021).png",
"thumb": "58_&#47Jewel 5&#47 with syllables (2021).thumb.png"
},
{
"title": "&#34Rotation&#34 vocal chain (2019)",
"media": "63_&#47Rotation&#47 vocal chain (2019).png",
"thumb": "63_&#47Rotation&#47 vocal chain (2019).thumb.png"
}
]
},
{
"title": "Indra's Net - Notebooks",
"parent_dir": "images",
"media": "6_Indra's Net - Notebooks",
"order": "6",
"images": [
{
"title": "on sound",
"details": "continued (2018-2020)",
"media": "02_on sound, continued (2018-2020).png",
"thumb": "02_on sound, continued (2018-2020).thumb.png"
},
{
"title": "variations for rehearsals",
"details": "on sound dimensions (2018-2020)",
"media": "05_variations for rehearsals, on sound dimensions (2018-2020).png",
"thumb": "05_variations for rehearsals, on sound dimensions (2018-2020).thumb.png"
},
{
"title": "on &#34Rotation&#34 (2018-2020)",
"media": "06_on &#47Rotation&#47 (2018-2020).png",
"thumb": "06_on &#47Rotation&#47 (2018-2020).thumb.png"
},
{
"title": "&#34Indra's Net&#34 form 2 (2020-2022)",
"media": "07_&#47Indra's Net&#47 form 2 (2020-2022).png",
"thumb": "07_&#47Indra's Net&#47 form 2 (2020-2022).thumb.png"
},
{
"title": "&#34Rotation&#34 - Indra principles (2020-2022)",
"media": "08_&#47Rotation&#47 - Indra principles (2020-2022).png",
"thumb": "08_&#47Rotation&#47 - Indra principles (2020-2022).thumb.png"
},
{
"title": "on sound (2018-2020)",
"media": "01_on sound (2018-2020).png",
"thumb": "01_on sound (2018-2020).thumb.png"
},
{
"title": "on time (2018-2020)",
"media": "03_on time (2018-2020).png",
"thumb": "03_on time (2018-2020).thumb.png"
},
{
"title": "images for projection (2018-2020)",
"media": "04_images for projection (2018-2020).png",
"thumb": "04_images for projection (2018-2020).thumb.png"
},
{
"title": "films for projection (2023)",
"media": "09_films for projection (2023).png",
"thumb": "09_films for projection (2023).thumb.png"
},
{
"title": "for Film A and Film B (2023)",
"media": "10_for Film A and Film B (2023).png",
"thumb": "10_for Film A and Film B (2023).thumb.png"
},
{
"title": "movement ideas (2023)",
"media": "11_movement ideas (2023).png",
"thumb": "11_movement ideas (2023).thumb.png"
},
{
"title": "for Film I (2023)",
"media": "12_for Film I (2023).png",
"thumb": "12_for Film I (2023).thumb.png"
},
{
"title": "sections and films chart (2023)",
"media": "13_sections and films chart (2023).png",
"thumb": "13_sections and films chart (2023).thumb.png"
}
]
},
{
"title": "Indra's Net - Visual Script",
"parent_dir": "images",
"media": "7_Indra's Net - Visual Script",
"order": "7",
"images": [
{
"title": "for performances at the Holland Festival (2023) Page 1",
"media": "01_for performances at the Holland Festival (2023) Page 1.jpg",
"thumb": "01_for performances at the Holland Festival (2023) Page 1.thumb.jpg"
},
{
"title": "for performances at the Holland Festival (2023) Page 2",
"media": "02_for performances at the Holland Festival (2023) Page 2.jpg",
"thumb": "02_for performances at the Holland Festival (2023) Page 2.thumb.jpg"
},
{
"title": "for performances at the Holland Festival (2023) Page 3",
"media": "03_for performances at the Holland Festival (2023) Page 3.jpg",
"thumb": "03_for performances at the Holland Festival (2023) Page 3.thumb.jpg"
},
{
"title": "for performances at the Holland Festival (2023) Page 4",
"media": "04_for performances at the Holland Festival (2023) Page 4.jpg",
"thumb": "04_for performances at the Holland Festival (2023) Page 4.thumb.jpg"
},
{
"title": "for performances at the Holland Festival (2023) Page 5",
"media": "05_for performances at the Holland Festival (2023) Page 5.jpg",
"thumb": "05_for performances at the Holland Festival (2023) Page 5.thumb.jpg"
},
{
"title": "for performances at the Holland Festival (2023) Page 6",
"media": "06_for performances at the Holland Festival (2023) Page 6.jpg",
"thumb": "06_for performances at the Holland Festival (2023) Page 6.thumb.jpg"
}
]
}
]

View File

@ -1 +1,430 @@
[]
[
{
"title": "Meredith Monk performing Epitaph by Donald Ashwander",
"details": "1980",
"parent_dir": "music_sound_unpublished",
"media": "1. Meredith Monk performing Epitaph by Donald Ashwander, 1980",
"order": "1",
"album": true,
"tracks": [
{
"title": "1.Epitaph Meredith Monk sings the music of Donald Ashwander 1980",
"media": "1.Epitaph_Meredith Monk sings the music of Donald Ashwander_1980.mp3"
}
]
},
{
"title": "Meredith Monk performing The Locust by Donald Ashwander",
"details": "1980",
"parent_dir": "music_sound_unpublished",
"media": "2. Meredith Monk performing The Locust by Donald Ashwander, 1980",
"order": "2",
"album": true,
"tracks": [
{
"title": "1.The Locust Meredith Monk sings the music of Donald Ashwander 1980",
"media": "1.The Locust_Meredith Monk sings the music of Donald Ashwander_1980.mp3"
}
]
},
{
"title": "Meredith Monk performing Aria by John Cage",
"details": "introduced by John Cage, Catskill Festival, New York, 1985",
"parent_dir": "music_sound_unpublished",
"media": "3. Meredith Monk performing Aria by John Cage, introduced by John Cage, Catskill Festival, New York, 1985",
"order": "3",
"album": true,
"tracks": [
{
"title": "1.Meredith Monk performing Aria by John Cage",
"media": "1.Meredith Monk performing Aria by John Cage.mp3"
}
]
},
{
"title": "Meredith Monk in Concert",
"details": "Willisau Jazz Festival, Switzerland, 1987",
"parent_dir": "music_sound_unpublished",
"media": "4. Meredith Monk in Concert, Willisau Jazz Festival, Switzerland, 1987",
"order": "4",
"album": true,
"tracks": [
{
"title": "Announcer MM speaks Porch 1",
"media": "01 Announcer_MM speaks_Porch_1.mp3"
},
{
"title": "Mesa",
"media": "02 Mesa.mp3"
},
{
"title": "Jade (Old Woman's Song)",
"media": "03 Jade (Old Woman's Song).mp3"
},
{
"title": "Wa-lie-oh",
"media": "04 Wa-lie-oh.mp3"
},
{
"title": "Insect",
"media": "05 Insect.mp3"
},
{
"title": "Descending",
"media": "06 Descending.mp3"
},
{
"title": "Silo (Drone)",
"media": "07 Silo (Drone).mp3"
},
{
"title": "Breath Song",
"media": "08 Breath Song.mp3"
},
{
"title": "Bird Code",
"media": "09 Bird Code.mp3"
},
{
"title": "Lullaby #4",
"media": "10 Lullaby #4.mp3"
},
{
"title": "Prairie Ghost",
"media": "11 Prairie Ghost.mp3"
},
{
"title": "Prairie Ghost",
"media": "12 Prairie Ghost.mp3"
},
{
"title": "Jew's Harp",
"media": "13 Jew's Harp.mp3"
},
{
"title": "Scared Song",
"media": "14 Scared Song.mp3"
},
{
"title": "Travelling",
"media": "15 Travelling.mp3"
},
{
"title": "I Don't Know",
"media": "16 I Don't Know.mp3"
},
{
"title": "I Don't Know cont-",
"media": "17 I Don't Know cont-.mp3"
},
{
"title": "Window in 7's Double Fiesta",
"media": "18 Window in 7's_Double Fiesta.mp3"
},
{
"title": "Double Fiesta cont",
"media": "19 Double Fiesta cont.mp3"
},
{
"title": "Do You Be",
"media": "20 Do You Be.mp3"
},
{
"title": "Ellis Island",
"media": "21 Ellis Island.mp3"
},
{
"title": "The Tale",
"media": "22 The Tale.mp3"
}
]
},
{
"title": "Double Fiesta",
"details": "recorded by Meredith Monk, Edmund Niemann and Nurit Tilles, Take 3 for ECM Records, 1987",
"parent_dir": "music_sound_unpublished",
"media": "5. Double Fiesta, recorded by Meredith Monk, Edmund Niemann and Nurit Tilles, Take 3 for ECM Records, 1987",
"order": "5",
"album": true,
"tracks": [
{
"title": "1. Double Fiesta, Take 3 ECM takes, 1987",
"media": "1. Double Fiesta, Take 3_ECM takes, 1987.mp3"
}
]
},
{
"title": "Double Fiesta",
"details": "recorded by Meredith Monk, Edmund Niemann and Nurit Tilles, Take 5 for ECM Records,1987",
"parent_dir": "music_sound_unpublished",
"media": "6. Double Fiesta, recorded by Meredith Monk, Edmund Niemann and Nurit Tilles, Take 5 for ECM Records,1987",
"order": "6",
"album": true,
"tracks": [
{
"title": "1. Double Fiesta- Take 5 ECM takes, 1987",
"media": "1. Double Fiesta- Take 5_ECM takes, 1987.mp3"
}
]
},
{
"title": "Meredith Monk and Bobby McFerrin",
"details": "Duet Behavior, Brooklyn Academy of Music (BAM), New York, 1987",
"parent_dir": "music_sound_unpublished",
"media": "7. Meredith Monk and Bobby McFerrin, Duet Behavior, Brooklyn Academy of Music (BAM), New York, 1987",
"order": "7",
"album": true,
"tracks": [
{
"title": "1. Dependent Song by Meredith Monk BAM 1987 2023 edit",
"media": "1. Dependent Song_by Meredith Monk_BAM 1987_2023 edit.mp3"
},
{
"title": "2. Cat by Meredith Monk and Bobby McFerrin BAM",
"media": "2. Cat by Meredith Monk and Bobby McFerrin BAM.mp3"
},
{
"title": "3. Sea Song by Meredith Monk and Bobby McFerrin BAM 1987",
"media": "3. Sea Song by Meredith Monk and Bobby McFerrin BAM 1987.mp3"
}
]
},
{
"title": "Cat",
"details": "recorded by Meredith Monk, 1988",
"parent_dir": "music_sound_unpublished",
"media": "8. Cat, recorded by Meredith Monk, 1988",
"order": "8",
"album": true,
"tracks": [
{
"title": "1. Cat, 1988",
"media": "1. Cat, 1988.mp3"
}
]
},
{
"title": "Come and Go (excerpt from Book of Days)",
"details": "performed by Meredith Monk & Vocal Ensemble, Organised by David Byrne, 1989",
"parent_dir": "music_sound_unpublished",
"media": "9. Come and Go (excerpt from Book of Days), performed by Meredith Monk & Vocal Ensemble, Organised by David Byrne, 1989",
"order": "9",
"album": true,
"tracks": [
{
"title": "1.Come and Go (Excerpt from Book of Days)",
"media": "1.Come and Go (Excerpt from Book of Days).mp3"
}
]
},
{
"title": "Meredith Monk in Concert",
"details": "Porch, Light Songs and Madwoman's Vision, Other Minds Festival, San Francisco, 1993",
"parent_dir": "music_sound_unpublished",
"media": "10. Meredith Monk in Concert, Porch, Light Songs and Madwoman's Vision, Other Minds Festival, San Francisco, 1993",
"order": "10",
"album": true,
"tracks": [
{
"title": "1. Light Songs, Madwoman's Vision",
"media": "1. Light Songs, Madwoman's Vision.mp3"
}
]
},
{
"title": "Disappearance I from Volcano Songs",
"details": "recorded by Meredith Monk, 1994",
"parent_dir": "music_sound_unpublished",
"media": "11. Disappearance I from Volcano Songs, recorded by Meredith Monk, 1994",
"order": "11",
"album": true,
"tracks": [
{
"title": "1. Disappearance 1 from Volcano Songs 1994",
"media": "1. Disappearance 1 from Volcano Songs 1994.mp3"
}
]
},
{
"title": "Disappearance II from Volcano Songs",
"details": "recorded by Meredith Monk, 1994",
"parent_dir": "music_sound_unpublished",
"media": "12. Disappearance II from Volcano Songs, recorded by Meredith Monk, 1994",
"order": "12",
"album": true,
"tracks": [
{
"title": "1. Disappearance 2 from Volcano Songs 1994",
"media": "1. Disappearance 2 from Volcano Songs_1994.mp3"
}
]
},
{
"title": "Steppe Music (world premiere)",
"details": "performed by Nurit Tilles, San Francisco, 1997",
"parent_dir": "music_sound_unpublished",
"media": "13. Steppe Music (world premiere), performed by Nurit Tilles, San Francisco, 1997",
"order": "13",
"album": true,
"tracks": [
{
"title": "1. Steppe Music premiere Nurit Tilles in San Francisco, 1997",
"media": "1. Steppe Music premiere_Nurit Tilles in San Francisco, 1997.mp3"
}
]
},
{
"title": "Name Songs (3 Tracy Birthday Songs)",
"details": "recorded by Meredith Monk, 1998",
"parent_dir": "music_sound_unpublished",
"media": "14. Name Songs (3 Tracy Birthday Songs), recorded by Meredith Monk, 1998",
"order": "14",
"album": true,
"tracks": [
{
"title": "1. Birthday Variations for Tracy 1998",
"media": "1. Birthday Variations for Tracy_1998.mp3"
}
]
},
{
"title": "Boys",
"details": "written by Rick Moody, music by Meredith Monk, read by Julia Slavin, WNYC radio show, 1999",
"parent_dir": "music_sound_unpublished",
"media": "15. Boys, written by Rick Moody, music by Meredith Monk, read by Julia Slavin, WNYC radio show, 1999",
"order": "15",
"album": true,
"tracks": [
{
"title": "1. Boys- WNYC show 1999 OR JUST MUSIC ",
"media": "1. Boys- WNYC show__1999_OR JUST MUSIC_.mp3"
}
]
},
{
"title": "Ancestor Shout",
"details": "performed by Meredith Monk and David Behrman, Roulette, NYC, 2001",
"parent_dir": "music_sound_unpublished",
"media": "16. Ancestor Shout, performed by Meredith Monk and David Behrman, Roulette, NYC, 2001",
"order": "16",
"album": true,
"tracks": [
{
"title": "1.Ancestor Shout Meredith Monk and David Behrman ",
"media": "1.Ancestor Shout_Meredith Monk and David Behrman_.mp3"
}
]
},
{
"title": "Little Breath Motor",
"details": "performed by Meredith Monk and David Behrman, Roulette, NYC, 2001",
"parent_dir": "music_sound_unpublished",
"media": "17. Little Breath Motor, performed by Meredith Monk and David Behrman, Roulette, NYC, 2001",
"order": "17",
"album": true,
"tracks": [
{
"title": "1. Little Breath Motor Meredith Monk and David Behrman ",
"media": "1. Little Breath Motor_Meredith Monk and David Behrman_.mp3"
}
]
},
{
"title": "Realm Variations",
"details": "performed by Meredith Monk & Vocal Ensemble and San Francisco Symphony, 2012",
"parent_dir": "music_sound_unpublished",
"media": "18. Realm Variations, performed by Meredith Monk & Vocal Ensemble and San Francisco Symphony, 2012",
"order": "18",
"album": true,
"tracks": [
{
"title": "1. Realm Variations-San Francisco Symphony and Meredith Monk",
"media": "1. Realm Variations-San Francisco Symphony and Meredith Monk.mp3"
}
]
},
{
"title": "WEAVE for Two Voices",
"details": "Chamber Orchestra and Chorus, rehearsal with Theo Bleckmann, Katie Geissinger, St.Louis Symphony and Chorus, 2015",
"parent_dir": "music_sound_unpublished",
"media": "19. WEAVE for Two Voices, Chamber Orchestra and Chorus, rehearsal with Theo Bleckmann, Katie Geissinger, St.Louis Symphony and Chorus, 2015",
"order": "19",
"album": true,
"tracks": [
{
"title": "1. Weave",
"media": "1. Weave.mp3"
}
]
},
{
"title": "Backlight",
"details": "performed by Ensemble ACJW, 2015",
"parent_dir": "music_sound_unpublished",
"media": "20. Backlight, performed by Ensemble ACJW, 2015",
"order": "20",
"album": true,
"tracks": [
{
"title": "1.Backlight",
"media": "1.Backlight.mp3"
}
]
},
{
"title": "Name Song (Wedding Song for Will and Lindsey)",
"details": "recorded by Meredith Monk, 2020",
"parent_dir": "music_sound_unpublished",
"media": "21. Name Song (Wedding Song for Will and Lindsey), recorded by Meredith Monk, 2020",
"order": "21",
"album": true,
"tracks": [
{
"title": "1.Wedding Song for Will and Lindsey-final mix 2020 1",
"media": "1.Wedding Song for Will and Lindsey-final mix_2020_1.mp3"
}
]
},
{
"title": "Name Song (Declan Birthday Song)",
"details": "recorded by Meredith Monk, 2020",
"parent_dir": "music_sound_unpublished",
"media": "22. Name Song (Declan Birthday Song), recorded by Meredith Monk, 2020",
"order": "22",
"album": true,
"tracks": [
{
"title": "1.Declan Birthday Song 2020",
"media": "1.Declan Birthday Song_2020.mp3"
}
]
},
{
"title": "Name Song (Isla Birthday Song)",
"details": "recorded by Meredith Monk, 2020",
"parent_dir": "music_sound_unpublished",
"media": "23. Name Song (Isla Birthday Song), recorded by Meredith Monk, 2020",
"order": "23",
"album": true,
"tracks": [
{
"title": "1. Isla Birthday Song October 2016 1",
"media": "1. Isla Birthday Song_October 2016_1.mp3"
}
]
},
{
"title": "Simple Sorrow",
"details": "Meredith Monk, 2020",
"parent_dir": "music_sound_unpublished",
"media": "24. Simple Sorrow, Meredith Monk, 2020",
"order": "24",
"album": true,
"tracks": [
{
"title": "1.Simple Sorrow, Meredith Monk",
"media": "1.Simple Sorrow, Meredith Monk.mp3"
}
]
}
]

View File

@ -61,5 +61,12 @@
"parent_dir": "theatre",
"media": "impermanence_Brooklyn Academy of Music (BAM), New York, 2006.mp4",
"image": "impermanence_Brooklyn Academy of Music (BAM), New York, 2006.jpg"
},
{
"title": "Indra's Net (world premiere)",
"details": "presented by Holland Festival & Hartig Art Foundation, Gashouder, Westergas Fabriek, Amsterdam, The Netherlands, 2023",
"parent_dir": "theatre",
"media": "3012_INDRA'S NET_GROTEKERK_EXPO_DEF-H264 for iPad.m4v",
"image": "3012_INDRA'S NET_GROTEKERK_EXPO_DEF-H264 for iPad.png"
}
]

View File

@ -23,6 +23,32 @@ async function generateWaveform(audioFile, outputDir) {
})
}
async function generateThumb(imgPath, outputDir) {
const { name, ext } = path.parse(imgPath)
if (!ext) {
return 0
}
const thumb = path.format({ name: `${name}.thumb`, ext })
const inputFile = path.join(outputDir, imgPath)
const outputFile = path.join(outputDir, thumb)
return new Promise((resolve, reject) => {
exec(
`magick "${inputFile}" -resize 250x250\\> "${outputFile}"`,
(error, stdout) => {
if (error) {
console.error(error)
reject(error)
} else {
resolve(thumb)
}
}
)
})
}
// MAIN FUNCTION
async function main() {
// variable for incoming variable
@ -33,11 +59,32 @@ async function main() {
let dryRun = false
let formatted = null
let waveform = false
let update = []
let order = false
if (process.argv.length < 3 || process.argv.includes('-h')) {
console.log(`
Files to Json converter
Commands :
-h : This message
-dir : The input directory to scan
-o : The output directory of the json file. If not set will default to current working directory
-u : [NOT IMPLEMENTED] List of comma separated feilds to update. Will only overwrite that which is set
-r : Recurse the directory (once) for sub-fields. Albums and image categories for example.
Other flags
--images-only : For a folder with only images, rather than media files with associated thumbs.
--dry-run : Output to the console
--formatted : Directory or file name, will format on the the undersore : "title_details".
This takes the arguments, parent, recurse or both. Defaults to both.
--gen-waveform : [may break if recursing] If going through audio files can generate waveform images for the file.
--order : Take number & number + "." as order of array
`)
return
}
// get command line arguments
process.argv.forEach(function (val, index) {
// console.log(index + ': ' + val)
process.argv.forEach((val, index) => {
switch (val) {
case '-dir':
mediaDir = process.argv[index + 1] || ''
@ -69,12 +116,19 @@ async function main() {
dryRun = true
break
case '--formatted':
formatted = ['parent', 'recurse', 'both' ].includes(process.argv[index + 1]) ? process.argv[index + 1] : 'both'
formatted = [
'parent',
'recurse',
'both' ].includes(
process.argv[index + 1]
) ? process.argv[index + 1] : 'both'
break
case '--gen-waveform':
waveform = true
break
case '--order':
order = true
break
default:
break
}
@ -93,11 +147,9 @@ async function main() {
let media = []
let images = []
// If recursing we are making the "media" the directories where we will find the
// acutal media to playback or see
if (recurse) {
media = dirList.filter(i => !i.match(/\.[^/.]+$/))
media = dirList.filter(i => !i.match(/\.[^/.]{1,4}$/))
} else {
media = dirList.filter(i => i.match(/.(mp\d|m\d\w)$/i))
}
@ -120,10 +172,17 @@ async function main() {
// setup structure
const _r = {
...genMetadata(m, formatted == 'parent' || formatted == 'both'),
...genMetadata(m, formatted == 'parent' || formatted == 'both', order),
parent_dir,
media: m,
image: ''
image: '',
order: 0
}
if (order) {
const idx = m.match(/\d+/) ? m.match(/\d+/)[0] : 0
_r.order = idx
_r.title = _r.title.replace(/^\d+\W*_*/, '')
}
// if we are scanning for images only, remove the 'image' property
@ -149,26 +208,52 @@ async function main() {
let files = await fs.readdir(rDir)
// filterout any rogue folders
// generate the metadata for each file
files = files.filter(f => f.match(/\.[^/.]+$/))
files = files.filter(f => f.match(/(?<!\.thumb)\.[^.]+$/))
files = files.map(f => {
const { title, details } = genMetadata(f, formatted == 'recurse' || formatted == 'both')
return { title, details, media: f }
const { title, details } = genMetadata(f, formatted == 'recurse' || formatted == 'both', false)
return { title, details, media: f }
})
// sort files by leading nuber (if exists)
files.sort((a, b) => {
const valA = a.title.match(/\d+/) ? a.title.match(/\d+/)[0] : 0
const valB = b.title.match(/\d+/) ? b.title.match(/\d+/)[0] : 0
return parseInt(valA) - parseInt(valB)
})
// remove leading number from tile &
// sanitize title for html unicode characters
files.forEach(f => {
f.title = f.title.replace(/^\d+(\s+|_)/, '')
f.title = f.title.replaceAll('&#47', '&#34')
})
// if images only
if (imagesOnly) {
// setup object per image in array
_r.images = files
_r.images = files.filter(f => !f.media.match(/\.thumb\.[^/.]{1,4}$/i))
} else {
_r.album = true
_r.tracks = files
}
}
if (imagesOnly) {
_r.images = await Promise.all(_r.images.map(async i => {
return { ...i, thumb: await generateThumb(i.media, path.join(mediaDir, _r.media)) }
}))
}
// return the result to the 'obj' variable
return _r
}))
if (order) {
obj.sort((a, b) => {
return a.order - b.order
})
}
// turn the obj variable into JSON
const json = JSON.stringify(obj, null, 2)
@ -190,22 +275,28 @@ async function main() {
}
}
function genMetadata(dir, formatted) {
function genMetadata(path, formatted) {
let title, details
const cleanPath = path.replace(/^\d+(_|.)/, '')
// if formatted flag set
if (formatted) {
// split the incoming name from the map on the '_'
// and set the first element to title, and the second to details
let [ t, d ] = dir.split('_')
let [ t, _, d ] = cleanPath.split(/(,|_)(.+)/s)
// assign to return object
title = t
details = d ? d.replace(/\.+(mp\d|m\dv)$/i, '') : ''
details = d ? d.replace(/\.+(mp\d|m\dv)$/i, '').trim() : ''
} else {
// else just set title to filename without extensions
title = dir.replace(/\.[^/.]+$/, '')
const name = cleanPath.replace(/\.\S{3,4}$/, '')
title = name.replace(/_/g, ' ')
}
title = title.replace(/\.\w+$/, '')
details = details ? details.replace(/\.\w+$/, '') : undefined
return { title, details }
}

View File

@ -1,64 +0,0 @@
import fs from 'fs/promises'
import path from 'path'
import { watch } from 'chokidar'
function main() {
let watchDir = ''
let sections = []
process.argv.forEach((val, i) => {
switch (val) {
case '-i':
watchDir = process.argv[i + 1] || ''
break
default:
break
}
})
if (!watchDir) {
console.error('no directory passed')
}
const w = watch(watchDir, {
persistent: true,
awaitWriteFinish: {
stabilityThreshold: 2000,
pollInterval: 100
},
})
w.on('ready',() => {
console.log('Watching', watchDir, 'for changes.')
// check each section against json file
console.log(sections)
})
w.on('add', (filePath) => {
fileAddedHandler(filePath, sections)
})
w.on('change', path => console.log(`File ${path} has been changed`))
w.on('unlink', path => console.log(`File ${path} has been removed`))
}
function fileAddedHandler(filePath, array) {
let section, media
let fp = filePath.replace(/^\.+/, '')
fp = path.parse(fp).dir.split(path.sep)
console.log(fp)
// 5 is recurse 4 is not
console.log(fp[3], fp.length)
section = fp[3]
media = fp[4]
console.log(media)
}
main()

View File

@ -1,6 +1,5 @@
import { LitElement, css, html, unsafeCSS } from 'lit'
import Router from './api/Router.js'
import { Task } from '@lit-labs/task'
import MainCSS from './assets/styles/main.scss?inline'
@ -35,18 +34,23 @@ export class App extends LitElement {
this.addEventListener('single-fullscreen-image', ({ detail }) => {
const { src, details } = detail
const grid = document.createElement('div')
grid.classList.add('grid')
const img = new Image()
img.src = src
this.dialogEl.appendChild(img)
grid.appendChild(img)
if (detail.details) {
const div = document.createElement('div')
const p = document.createElement('p')
p.textContent = details
p.innerHTML = details
div.appendChild(p)
this.dialogEl.appendChild(div)
grid.appendChild(div)
}
this.dialogEl.appendChild(grid)
this.dialogEl.showModal()
this.dialogEl.addEventListener('click', () => {
@ -61,8 +65,7 @@ export class App extends LitElement {
${Router.route.path == '/' ? '' : html`<mm-header title=${Router.route.title}></mm-header>`}
${Router.render()}
${Router.route.path == '/' ? '' : html`<mm-footer path=${Router.route.path}></mm-footer>`}
<dialog class="popup">
</dialog>
<dialog class="popup"></dialog>
`
}
@ -77,16 +80,25 @@ export class App extends LitElement {
dialog {
margin: auto;
border: none;
outline: none;
height: 80svh;
& div {
& .grid {
display: grid;
grid-template-rows: minmax(0em, 1fr) auto;
height: 100%;
}
& .grid > div {
padding-block-start: 1em;
font-size: 1.25em;
}
& img {
& .grid > img {
display: block;
max-height: calc(100vmin - 2em);
max-width: calc(100vmin - 2em);
height: 100%;
width: 100%;
object-fit: contain;
}
}

View File

@ -52,7 +52,6 @@ export default new Router({
short: 'ECM',
icon: 'headphones',
group: 'Music & Sound',
disabled: true,
plugins: [
lazy(() => import('../views/audio.js'))
],
@ -75,7 +74,7 @@ export default new Router({
short: 'Unpublished',
icon: 'headphones',
group: 'Music & Sound',
disabled: true,
disabled: false,
plugins: [
lazy(() => import('../views/audio.js'))
],
@ -116,7 +115,7 @@ export default new Router({
title: 'Scores, Posters, Ephemera',
short: 'images',
icon: 'camera',
disabled: true,
disabled: false,
plugins: [
lazy(() => import('../views/images.js'))
],

View File

@ -33,7 +33,6 @@ class Footer extends LitElement {
}
})
const sortedArray = ungrouped
sortedArray.splice(1, 0, Object.values(grouped)[0])
sortedArray.splice(2, 0, Object.values(grouped)[1])
@ -41,15 +40,23 @@ class Footer extends LitElement {
this.navigation = sortedArray
}
navigate({ target }) {
const link = target.closest('.link')
if (link.dataset.href != Router.route.path) {
Router.navigate(link.dataset.href)
}
}
renderLink(r, first = false) {
return html`
${first ? html`<span class="break"></span>` : '' }
${!r.disabled ? html`<a href=${r.path} class="${r.path == this.path ? 'selected' : ''}">
${!r.disabled ? html`<span data-href=${r.path} class="link ${r.path == this.path ? 'selected' : ''}" @click=${this.navigate}>
<mm-icon name=${r.icon}></mm-icon>
<span>
${r.short}
</span>
</a>` : '' }
</span>` : '' }
`
}
@ -80,7 +87,7 @@ class Footer extends LitElement {
font-size: 0.9em;
}
a {
span.link {
display: flex;
padding-block: 0.25em;
gap: 0.25em;
@ -101,8 +108,8 @@ class Footer extends LitElement {
margin-inline-end: 0.5em;
}
a.selected {
color: var(--neutral-900, black);
.selected {
color: var(--neutral-900, black) !important;
}
.break {

View File

@ -38,7 +38,7 @@ class Header extends LitElement {
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
header {
padding-inline: 0.5em;
padding-block-end: 0.5em;
padding-block: 0.5em;
}
header > div {

View File

@ -176,15 +176,16 @@ class ModularPlayer extends LitElement {
render() {
return html`
${ this.details ?
html`<div class="player">
return this.details ? html`
<div class="player ${this.details.tracks ? 'tracks' : 'single'}">
<!-- render the tracklist -->
${this.details.tracks ? html`
<div class="tracklist">
<header>
<img src=${this.details.image}
${ this.details.image ? html`<img src=${this.details.image}
@click=${this.showImage}
/>
/>` : ''}
<h2>${this.details.title}</h2>
</header>
@ -200,56 +201,65 @@ ${ this.details ?
</div>
` : html``}
<header>
<h2>${this.details.tracks ? this.details?.tracks[this.track].title : this.details.title}</h2>
${this.details.tracks ? '' : html`<p class="details">${this.details.details}</p>`}
</header>
<!-- start of green -->
<div class="player-controls">
<!-- header -->
<header>
<h2>${this.details.tracks ? this.details?.tracks[this.track].title : this.details.title}</h2>
${this.details.tracks ? '' : html`<p class="details">${this.details.details}</p>`}
</header>
<div class="info">
${this._getTrack.render({
complete: () => html`
<span class="time_pos">${formatSeconds(this.position)}</span>
<!-- start of playback indicator -->
<div class="info">
${this._getTrack.render({
complete: () => html`
<span class="time_pos">${formatSeconds(this.position)}</span>
${this.details?.tracks ?
html`<mm-range
value=${this.position}
max=${this.duration}
step="0.1"
@input=${this._seekTrack}
></mm-range>`
: html`
<div class="waveform">
<mm-range
${this.details?.tracks ?
html`<mm-range
value=${this.position}
max=${this.duration}
step="0.1"
@input=${this._seekTrack}
class="progress"
></mm-range>
<img class="wav-img" loading="eager" src="${this.details.image}">
</div>
`
}
></mm-range>`
: html`
<div class="waveform">
<mm-range
value=${this.position}
max=${this.duration}
step="0.1"
@input=${this._seekTrack}
class="progress"
></mm-range>
<img class="wav-img" loading="eager" src="${this.details.image}">
</div>
`
}
<span class="time_dur">${formatSeconds(this.duration)}</span>
`,
error: (err) => err
})}
<span class="time_dur">${formatSeconds(this.duration)}</span>
`,
error: (err) => err
})}
${this.audio}
</div>
<div class="controls">
<div class="buttons">
<mm-icon name="skip-prev" @click=${this._prevTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
<mm-icon name="skip-b15" @click=${this._skipBackward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
<mm-icon name="${this.playing ? 'pause' : 'play'}" @click=${this._togglePlay} ?disabled=${!this.duration || this.getAudio?.status == 1} class=${this.playing ? 'pause' : 'play'}></mm-icon>
<mm-icon name="skip-f15" @click=${this._skipForward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
<mm-icon name="skip-next" @click=${this._nextTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
${this.audio}
</div>
<!-- controls -->
<div class="controls">
<div class="buttons">
<mm-icon name="skip-prev" @click=${this._prevTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
<mm-icon name="skip-b15" @click=${this._skipBackward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
<mm-icon name="${this.playing ? 'pause' : 'play'}" @click=${this._togglePlay} ?disabled=${!this.duration || this.getAudio?.status == 1} class=${this.playing ? 'pause' : 'play'}></mm-icon>
<mm-icon name="skip-f15" @click=${this._skipForward} ?disabled=${!this.duration || this.getAudio?.status == 1} class="skip15"></mm-icon>
<mm-icon name="skip-next" @click=${this._nextTrack} ?disabled=${!this.duration || this.getAudio?.status == 1}></mm-icon>
</div>
</div>
<!-- end of green -->
</div>
</div>
` : ''}`
<!-- end of player -->
`
: ''
}
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
@ -273,8 +283,7 @@ ${ this.details ?
}
.player:has(.tracklist) {
grid-template-rows: 67% 1fr 1fr 1fr;
padding-block-end: 2em;
grid-template-rows: 60% 40%;
gap: 0;
& > header {
@ -284,10 +293,31 @@ ${ this.details ?
& .info {
padding-block-end: 1.5em;
}
& .player-controls {
display: grid;
grid-template-rows: 5em repeat(2, 1fr);
padding: 1em;
& header {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 1.3em;
}
}
}
.player:has(.waveform) {
grid-template-rows: 0.7fr 0.7fr 1fr;
display: flex;
flex-direction: column;
& .player-controls {
flex-grow: 1;
display: grid;
grid-template-rows: repeat(3, 1fr);
}
& header {
padding-block-start: 1em;
@ -306,11 +336,6 @@ ${ this.details ?
max-width: 25ch;
}
.tracklist + header {
text-align: center;
font-size: 1.25em;
}
.tracklist {
--tracklist-padding: calc(var(--padding) * 2);
display: flex;
@ -324,7 +349,8 @@ ${ this.details ?
margin-block-end: 0.75em;
padding-block-start: 0.75em;
border-block-start: thin solid var(--green-400);
display: flex;
display: grid;
grid-template-columns: auto 1fr;
gap: 0.5em;
align-items: end;
color: black;
@ -332,10 +358,15 @@ ${ this.details ?
& img {
height: 4em;
aspect-ratio: 1 / 1;
grid-columns: 1 / span 1;
}
& > h2 {
line-height: 1;
grid-columns: 2 / span 1;
}
& img + h2 {
max-width: 15ch;
}
}

View File

@ -31,7 +31,7 @@ class VerticalCard extends LitElement {
return html`
<div @click=${this.select} class=${this.selected ? 'selected' : ''}>
<picture>
<img src="/media/${Router.route.path}/${this.details.image}">
<img src="${encodeURIComponent(`/media${Router.route.path}/${this.details.image}`)}">
</picture>
<aside>
<p class="title">${this.details?.title}</p>
@ -70,7 +70,6 @@ class VerticalCard extends LitElement {
picture {
display: block;
background: var(--image-placeholder);
/* aspect-ratio: 1 / 1; */
overflow: hidden;
}

View File

@ -54,6 +54,7 @@ class Home extends LitElement {
</nav>
<footer>
<p class="provided">All materials generously provided by Meredith Monk/The House Foundation for the Arts, Inc., New York</p>
<div>
<p>Rooms for Listening & Looking</p>
</div>
@ -121,7 +122,15 @@ class Home extends LitElement {
padding-block-end: 0.5em;
}
footer p {
.provided {
color: white;
padding: 0;
font-size: 0.75em;
margin: 0.5em 0.75em;
align-self: end;
}
footer div > p {
font-size: 1.5em;
font-weight: 500;
}

View File

@ -1,4 +1,5 @@
import { LitElement, css, html, unsafeCSS } from 'lit'
import {unsafeHTML} from 'lit/directives/unsafe-html.js'
import { Task } from '@lit-labs/task'
import Router from '../api/Router.js'
@ -27,7 +28,14 @@ class ImageView extends LitElement {
const res = await fetch('/data/images.json')
const json = await res.json()
json.forEach(i => i.path = `/media${Router.route.path}/${i.media}`)
json.forEach(i => {
console.log(i)
i.path = `/media${Router.route.path}/${i.media}`
}
)
console.log(json)
this.images = json
} catch (err) {
@ -41,7 +49,7 @@ class ImageView extends LitElement {
console.log(target.details)
const event = new CustomEvent('single-fullscreen-image', {
bubbles: true, composed: true,
detail: { ...target.details, src: `/media${Router.route.path}/${target.details.section}/${target.details.media}` }
detail: { ...target.details, src: encodeURIComponent(`/media${Router.route.path}/${target.details.section}/${target.details.media}`) }
})
this.dispatchEvent(event)
@ -49,8 +57,6 @@ class ImageView extends LitElement {
render() {
return html`
<!-- <mm-img-carousel .images=${this.images}></mm-img-carousel> -->
${this.images.length > 0 ?
html`
<div class="gallery">
@ -64,7 +70,7 @@ class ImageView extends LitElement {
i => html`
<mm-vcard
@click=${this.selectImage}
.details=${ { ...i, section: section.media } }
.details=${ { ...i, title: unsafeHTML(i.title), section: section.media, image: `${section.media}/${i.thumb}` } }
?selected=${i.title == this.selected?.title}
>
</mm-vcard>
@ -95,6 +101,7 @@ class ImageView extends LitElement {
mm-vcard {
--color: var(--green-400, lime);
--width: 8em;
}
header {
@ -108,8 +115,8 @@ class ImageView extends LitElement {
main {
display: grid;
gap: 0.75em;
grid-template-columns: repeat(7, 1fr);
grid-auto-rows: 10em;
grid-template-columns: repeat(5, 1fr);
grid-auto-rows: 15em;
}

View File

@ -66,9 +66,8 @@ class VideoView extends LitElement {
static styles = [ css`${unsafeCSS(MainCSS)}`, css`
:host {
flex-grow: 1;
height: 100%;
display: grid;
grid-template-rows: 1fr 0.55fr;
grid-template-rows: 1fr min(35%, 250px);
gap: 0.25em;
}