diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000000..12ba6a49531 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,29 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "never" + ] + } +} diff --git a/assets/chevron-down-solid.svg b/assets/chevron-down-solid.svg new file mode 100644 index 00000000000..b5ea5778f5b --- /dev/null +++ b/assets/chevron-down-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/chevron-up-solid.svg b/assets/chevron-up-solid.svg new file mode 100644 index 00000000000..e0848f3fb82 --- /dev/null +++ b/assets/chevron-up-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/expand_more-24px-4.svg b/assets/expand_more-24px-4.svg new file mode 100644 index 00000000000..46030f61259 --- /dev/null +++ b/assets/expand_more-24px-4.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/heart-icon-black.svg b/assets/heart-icon-black.svg new file mode 100644 index 00000000000..1013bfefd6c --- /dev/null +++ b/assets/heart-icon-black.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/heart.svg b/assets/heart.svg new file mode 100644 index 00000000000..9bda734a1fa --- /dev/null +++ b/assets/heart.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/close-btn.svg b/assets/icons/close-btn.svg new file mode 100644 index 00000000000..967d5ba636d --- /dev/null +++ b/assets/icons/close-btn.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/next-btn.svg b/assets/icons/next-btn.svg new file mode 100644 index 00000000000..af8f3e1c818 --- /dev/null +++ b/assets/icons/next-btn.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/prev-btn.svg b/assets/icons/prev-btn.svg new file mode 100644 index 00000000000..47723b98bfe --- /dev/null +++ b/assets/icons/prev-btn.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/Ellie-Rose Wilkens/Architecture_Connected_Curves.jpg b/assets/images/Ellie-Rose Wilkens/Architecture_Connected_Curves.jpg new file mode 100644 index 00000000000..56aeeea6024 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Architecture_Connected_Curves.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Architecture_Cross_Bar.jpg b/assets/images/Ellie-Rose Wilkens/Architecture_Cross_Bar.jpg new file mode 100644 index 00000000000..efdd811878a Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Architecture_Cross_Bar.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Architecture_Horseshoe.jpg b/assets/images/Ellie-Rose Wilkens/Architecture_Horseshoe.jpg new file mode 100644 index 00000000000..d6f231c7dda Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Architecture_Horseshoe.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Architecture_Water_on_Modern.jpg b/assets/images/Ellie-Rose Wilkens/Architecture_Water_on_Modern.jpg new file mode 100644 index 00000000000..af0712fad44 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Architecture_Water_on_Modern.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Architecture_White_Light.jpg b/assets/images/Ellie-Rose Wilkens/Architecture_White_Light.jpg new file mode 100644 index 00000000000..d5679f79dc7 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Architecture_White_Light.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Sport_Jump.jpg b/assets/images/Ellie-Rose Wilkens/Sport_Jump.jpg new file mode 100644 index 00000000000..d1582de0687 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Sport_Jump.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Sport_Next_Hold.jpg b/assets/images/Ellie-Rose Wilkens/Sport_Next_Hold.jpg new file mode 100644 index 00000000000..c0db72fd183 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Sport_Next_Hold.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Sport_Race_End.jpg b/assets/images/Ellie-Rose Wilkens/Sport_Race_End.jpg new file mode 100644 index 00000000000..74ce01abea4 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Sport_Race_End.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Sport_Sky_Cross.jpg b/assets/images/Ellie-Rose Wilkens/Sport_Sky_Cross.jpg new file mode 100644 index 00000000000..5e39b15d579 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Sport_Sky_Cross.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/Sport_Tricks_in_the_air.mp4 b/assets/images/Ellie-Rose Wilkens/Sport_Tricks_in_the_air.mp4 new file mode 100644 index 00000000000..a2d592235e4 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/Sport_Tricks_in_the_air.mp4 differ diff --git a/assets/images/Ellie-Rose Wilkens/sport_water_tunnel.jpg b/assets/images/Ellie-Rose Wilkens/sport_water_tunnel.jpg new file mode 100644 index 00000000000..df8ff6678a9 Binary files /dev/null and b/assets/images/Ellie-Rose Wilkens/sport_water_tunnel.jpg differ diff --git a/assets/images/Ellie-Rose Wilkens/video_preview.svg b/assets/images/Ellie-Rose Wilkens/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Ellie-Rose Wilkens/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/Marcel Nikolic/Architecture_Contrast.jpg b/assets/images/Marcel Nikolic/Architecture_Contrast.jpg new file mode 100644 index 00000000000..2195a5a0d8f Binary files /dev/null and b/assets/images/Marcel Nikolic/Architecture_Contrast.jpg differ diff --git a/assets/images/Marcel Nikolic/Architecture_Corner_Room.jpg b/assets/images/Marcel Nikolic/Architecture_Corner_Room.jpg new file mode 100644 index 00000000000..f5fdf79a85c Binary files /dev/null and b/assets/images/Marcel Nikolic/Architecture_Corner_Room.jpg differ diff --git a/assets/images/Marcel Nikolic/Architecture_Dome.jpg b/assets/images/Marcel Nikolic/Architecture_Dome.jpg new file mode 100644 index 00000000000..648dfa8e982 Binary files /dev/null and b/assets/images/Marcel Nikolic/Architecture_Dome.jpg differ diff --git a/assets/images/Marcel Nikolic/Architecture_On_a_hill.jpg b/assets/images/Marcel Nikolic/Architecture_On_a_hill.jpg new file mode 100644 index 00000000000..989f2bbb7f1 Binary files /dev/null and b/assets/images/Marcel Nikolic/Architecture_On_a_hill.jpg differ diff --git a/assets/images/Marcel Nikolic/Architecture_coverr_circle_empty_highway_in_buenos_aires_587740985637.mp4 b/assets/images/Marcel Nikolic/Architecture_coverr_circle_empty_highway_in_buenos_aires_587740985637.mp4 new file mode 100644 index 00000000000..30a926ad115 Binary files /dev/null and b/assets/images/Marcel Nikolic/Architecture_coverr_circle_empty_highway_in_buenos_aires_587740985637.mp4 differ diff --git a/assets/images/Marcel Nikolic/Travel_Adventure_Door.jpg b/assets/images/Marcel Nikolic/Travel_Adventure_Door.jpg new file mode 100644 index 00000000000..1312689296b Binary files /dev/null and b/assets/images/Marcel Nikolic/Travel_Adventure_Door.jpg differ diff --git a/assets/images/Marcel Nikolic/Travel_Bike_and_Stair.jpg b/assets/images/Marcel Nikolic/Travel_Bike_and_Stair.jpg new file mode 100644 index 00000000000..e532050dfba Binary files /dev/null and b/assets/images/Marcel Nikolic/Travel_Bike_and_Stair.jpg differ diff --git a/assets/images/Marcel Nikolic/Travel_OpenMountain.jpg b/assets/images/Marcel Nikolic/Travel_OpenMountain.jpg new file mode 100644 index 00000000000..86c5a3c4f7b Binary files /dev/null and b/assets/images/Marcel Nikolic/Travel_OpenMountain.jpg differ diff --git a/assets/images/Marcel Nikolic/Travel_SunsetonCanals.jpg b/assets/images/Marcel Nikolic/Travel_SunsetonCanals.jpg new file mode 100644 index 00000000000..1a94e34a82d Binary files /dev/null and b/assets/images/Marcel Nikolic/Travel_SunsetonCanals.jpg differ diff --git a/assets/images/Marcel Nikolic/Travel_Tower.jpg b/assets/images/Marcel Nikolic/Travel_Tower.jpg new file mode 100644 index 00000000000..954484d2164 Binary files /dev/null and b/assets/images/Marcel Nikolic/Travel_Tower.jpg differ diff --git a/assets/images/Marcel Nikolic/video_preview.svg b/assets/images/Marcel Nikolic/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Marcel Nikolic/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/Mimi Keel/.DS_Store b/assets/images/Mimi Keel/.DS_Store new file mode 100644 index 00000000000..5008ddfcf53 Binary files /dev/null and b/assets/images/Mimi Keel/.DS_Store differ diff --git a/assets/images/Mimi Keel/Animals_Rainbow.jpg b/assets/images/Mimi Keel/Animals_Rainbow.jpg new file mode 100644 index 00000000000..6cfc042f843 Binary files /dev/null and b/assets/images/Mimi Keel/Animals_Rainbow.jpg differ diff --git a/assets/images/Mimi Keel/Animals_Wild_Horses_in_the_mountains.mp4 b/assets/images/Mimi Keel/Animals_Wild_Horses_in_the_mountains.mp4 new file mode 100644 index 00000000000..d9c560dfbbc Binary files /dev/null and b/assets/images/Mimi Keel/Animals_Wild_Horses_in_the_mountains.mp4 differ diff --git a/assets/images/Mimi Keel/Event_BenevidesWedding.jpg b/assets/images/Mimi Keel/Event_BenevidesWedding.jpg new file mode 100644 index 00000000000..bf0413ce78a Binary files /dev/null and b/assets/images/Mimi Keel/Event_BenevidesWedding.jpg differ diff --git a/assets/images/Mimi Keel/Event_PintoWedding.jpg b/assets/images/Mimi Keel/Event_PintoWedding.jpg new file mode 100644 index 00000000000..5912d55410f Binary files /dev/null and b/assets/images/Mimi Keel/Event_PintoWedding.jpg differ diff --git a/assets/images/Mimi Keel/Event_SeasideWedding.jpg b/assets/images/Mimi Keel/Event_SeasideWedding.jpg new file mode 100644 index 00000000000..03ed8a4811f Binary files /dev/null and b/assets/images/Mimi Keel/Event_SeasideWedding.jpg differ diff --git a/assets/images/Mimi Keel/Portrait_Background.jpg b/assets/images/Mimi Keel/Portrait_Background.jpg new file mode 100644 index 00000000000..417c982a84f Binary files /dev/null and b/assets/images/Mimi Keel/Portrait_Background.jpg differ diff --git a/assets/images/Mimi Keel/Portrait_Nora.jpg b/assets/images/Mimi Keel/Portrait_Nora.jpg new file mode 100644 index 00000000000..1229f1d0226 Binary files /dev/null and b/assets/images/Mimi Keel/Portrait_Nora.jpg differ diff --git a/assets/images/Mimi Keel/Portrait_Wednesday.jpg b/assets/images/Mimi Keel/Portrait_Wednesday.jpg new file mode 100644 index 00000000000..4dbe4b02e4c Binary files /dev/null and b/assets/images/Mimi Keel/Portrait_Wednesday.jpg differ diff --git a/assets/images/Mimi Keel/Travel_HillsideColor.jpg b/assets/images/Mimi Keel/Travel_HillsideColor.jpg new file mode 100644 index 00000000000..32323aecc29 Binary files /dev/null and b/assets/images/Mimi Keel/Travel_HillsideColor.jpg differ diff --git a/assets/images/Mimi Keel/Travel_Lonesome.jpg b/assets/images/Mimi Keel/Travel_Lonesome.jpg new file mode 100644 index 00000000000..bb6fdc2e921 Binary files /dev/null and b/assets/images/Mimi Keel/Travel_Lonesome.jpg differ diff --git a/assets/images/Mimi Keel/video_preview.svg b/assets/images/Mimi Keel/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Mimi Keel/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/Nabeel Bradford/.DS_Store b/assets/images/Nabeel Bradford/.DS_Store new file mode 100644 index 00000000000..5008ddfcf53 Binary files /dev/null and b/assets/images/Nabeel Bradford/.DS_Store differ diff --git a/assets/images/Nabeel Bradford/Portrait_AfternoonBreak.jpg b/assets/images/Nabeel Bradford/Portrait_AfternoonBreak.jpg new file mode 100644 index 00000000000..3bb2ac52aee Binary files /dev/null and b/assets/images/Nabeel Bradford/Portrait_AfternoonBreak.jpg differ diff --git a/assets/images/Nabeel Bradford/Portrait_Alexandra.jpg b/assets/images/Nabeel Bradford/Portrait_Alexandra.jpg new file mode 100644 index 00000000000..cb68ff83388 Binary files /dev/null and b/assets/images/Nabeel Bradford/Portrait_Alexandra.jpg differ diff --git a/assets/images/Nabeel Bradford/Portrait_Shaw.jpg b/assets/images/Nabeel Bradford/Portrait_Shaw.jpg new file mode 100644 index 00000000000..ef96d47ea21 Binary files /dev/null and b/assets/images/Nabeel Bradford/Portrait_Shaw.jpg differ diff --git a/assets/images/Nabeel Bradford/Portrait_Sunkissed.jpg b/assets/images/Nabeel Bradford/Portrait_Sunkissed.jpg new file mode 100644 index 00000000000..564cd62780b Binary files /dev/null and b/assets/images/Nabeel Bradford/Portrait_Sunkissed.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_Boat_Wanderer.jpg b/assets/images/Nabeel Bradford/Travel_Boat_Wanderer.jpg new file mode 100644 index 00000000000..ed41f74a9bb Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_Boat_Wanderer.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_Bridge_into_Forest.jpg b/assets/images/Nabeel Bradford/Travel_Bridge_into_Forest.jpg new file mode 100644 index 00000000000..cd7ac1f3e4c Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_Bridge_into_Forest.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_On_the_Road.jpg b/assets/images/Nabeel Bradford/Travel_On_the_Road.jpg new file mode 100644 index 00000000000..6962233f1a9 Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_On_the_Road.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_Outdoor_Baths.jpg b/assets/images/Nabeel Bradford/Travel_Outdoor_Baths.jpg new file mode 100644 index 00000000000..58f7dc2482f Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_Outdoor_Baths.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_Road_into_Hill.jpg b/assets/images/Nabeel Bradford/Travel_Road_into_Hill.jpg new file mode 100644 index 00000000000..f8daa497283 Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_Road_into_Hill.jpg differ diff --git a/assets/images/Nabeel Bradford/Travel_Rock_Mountains.mp4 b/assets/images/Nabeel Bradford/Travel_Rock_Mountains.mp4 new file mode 100644 index 00000000000..92de1f6d63d Binary files /dev/null and b/assets/images/Nabeel Bradford/Travel_Rock_Mountains.mp4 differ diff --git a/assets/images/Nabeel Bradford/video_preview.svg b/assets/images/Nabeel Bradford/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Nabeel Bradford/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/Rhode Dubois/Animals_Majesty.jpg b/assets/images/Rhode Dubois/Animals_Majesty.jpg new file mode 100644 index 00000000000..d06eee63d79 Binary files /dev/null and b/assets/images/Rhode Dubois/Animals_Majesty.jpg differ diff --git a/assets/images/Rhode Dubois/Animals_Puppiness.mp4 b/assets/images/Rhode Dubois/Animals_Puppiness.mp4 new file mode 100644 index 00000000000..6d50831efe2 Binary files /dev/null and b/assets/images/Rhode Dubois/Animals_Puppiness.mp4 differ diff --git a/assets/images/Rhode Dubois/Event_Emcee.jpg b/assets/images/Rhode Dubois/Event_Emcee.jpg new file mode 100644 index 00000000000..b553079359e Binary files /dev/null and b/assets/images/Rhode Dubois/Event_Emcee.jpg differ diff --git a/assets/images/Rhode Dubois/Event_KeyboardCheck.jpg b/assets/images/Rhode Dubois/Event_KeyboardCheck.jpg new file mode 100644 index 00000000000..4ed239031fd Binary files /dev/null and b/assets/images/Rhode Dubois/Event_KeyboardCheck.jpg differ diff --git a/assets/images/Rhode Dubois/Event_ProductPitch.jpg b/assets/images/Rhode Dubois/Event_ProductPitch.jpg new file mode 100644 index 00000000000..1f612804aee Binary files /dev/null and b/assets/images/Rhode Dubois/Event_ProductPitch.jpg differ diff --git a/assets/images/Rhode Dubois/Event_VentureConference.jpg b/assets/images/Rhode Dubois/Event_VentureConference.jpg new file mode 100644 index 00000000000..7b9f1974d3e Binary files /dev/null and b/assets/images/Rhode Dubois/Event_VentureConference.jpg differ diff --git a/assets/images/Rhode Dubois/Fashion_Melody_Red_on_Stripes.jpg b/assets/images/Rhode Dubois/Fashion_Melody_Red_on_Stripes.jpg new file mode 100644 index 00000000000..531ff86aa88 Binary files /dev/null and b/assets/images/Rhode Dubois/Fashion_Melody_Red_on_Stripes.jpg differ diff --git a/assets/images/Rhode Dubois/Fashion_Wings.jpg b/assets/images/Rhode Dubois/Fashion_Wings.jpg new file mode 100644 index 00000000000..8b34274ba5d Binary files /dev/null and b/assets/images/Rhode Dubois/Fashion_Wings.jpg differ diff --git a/assets/images/Rhode Dubois/Sport_2000_with_8.jpg b/assets/images/Rhode Dubois/Sport_2000_with_8.jpg new file mode 100644 index 00000000000..9b9dd1b6098 Binary files /dev/null and b/assets/images/Rhode Dubois/Sport_2000_with_8.jpg differ diff --git a/assets/images/Rhode Dubois/Sport_Butterfly.jpg b/assets/images/Rhode Dubois/Sport_Butterfly.jpg new file mode 100644 index 00000000000..d7072b8a43b Binary files /dev/null and b/assets/images/Rhode Dubois/Sport_Butterfly.jpg differ diff --git a/assets/images/Rhode Dubois/video_preview.svg b/assets/images/Rhode Dubois/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Rhode Dubois/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/Tracy Galindo/Art_Mine.jpg b/assets/images/Tracy Galindo/Art_Mine.jpg new file mode 100644 index 00000000000..35d8031f871 Binary files /dev/null and b/assets/images/Tracy Galindo/Art_Mine.jpg differ diff --git a/assets/images/Tracy Galindo/Art_Purple_light.jpg b/assets/images/Tracy Galindo/Art_Purple_light.jpg new file mode 100644 index 00000000000..02153b641e0 Binary files /dev/null and b/assets/images/Tracy Galindo/Art_Purple_light.jpg differ diff --git a/assets/images/Tracy Galindo/Art_Triangle_Man.jpg b/assets/images/Tracy Galindo/Art_Triangle_Man.jpg new file mode 100644 index 00000000000..0234e0629a9 Binary files /dev/null and b/assets/images/Tracy Galindo/Art_Triangle_Man.jpg differ diff --git a/assets/images/Tracy Galindo/Art_Wooden_Horse_Sculpture.mp4 b/assets/images/Tracy Galindo/Art_Wooden_Horse_Sculpture.mp4 new file mode 100644 index 00000000000..91791cc73a4 Binary files /dev/null and b/assets/images/Tracy Galindo/Art_Wooden_Horse_Sculpture.mp4 differ diff --git a/assets/images/Tracy Galindo/Event_18thAnniversary.jpg b/assets/images/Tracy Galindo/Event_18thAnniversary.jpg new file mode 100644 index 00000000000..1a9d7128271 Binary files /dev/null and b/assets/images/Tracy Galindo/Event_18thAnniversary.jpg differ diff --git a/assets/images/Tracy Galindo/Event_Sparklers.jpg b/assets/images/Tracy Galindo/Event_Sparklers.jpg new file mode 100644 index 00000000000..8a8ea04c942 Binary files /dev/null and b/assets/images/Tracy Galindo/Event_Sparklers.jpg differ diff --git a/assets/images/Tracy Galindo/Event_WeddingGazebo.jpg b/assets/images/Tracy Galindo/Event_WeddingGazebo.jpg new file mode 100644 index 00000000000..3851ba5ed32 Binary files /dev/null and b/assets/images/Tracy Galindo/Event_WeddingGazebo.jpg differ diff --git a/assets/images/Tracy Galindo/Fashion_Pattern_on_Pattern.jpg b/assets/images/Tracy Galindo/Fashion_Pattern_on_Pattern.jpg new file mode 100644 index 00000000000..856f2bd5d3d Binary files /dev/null and b/assets/images/Tracy Galindo/Fashion_Pattern_on_Pattern.jpg differ diff --git a/assets/images/Tracy Galindo/Fashion_Urban_Jungle.jpg b/assets/images/Tracy Galindo/Fashion_Urban_Jungle.jpg new file mode 100644 index 00000000000..c623ed12b7b Binary files /dev/null and b/assets/images/Tracy Galindo/Fashion_Urban_Jungle.jpg differ diff --git a/assets/images/Tracy Galindo/Fashion_Yellow_Beach.jpg b/assets/images/Tracy Galindo/Fashion_Yellow_Beach.jpg new file mode 100644 index 00000000000..d7ac076640b Binary files /dev/null and b/assets/images/Tracy Galindo/Fashion_Yellow_Beach.jpg differ diff --git a/assets/images/Tracy Galindo/video_preview.svg b/assets/images/Tracy Galindo/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/images/Tracy Galindo/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/photographers/EllieRoseWilkens.jpg b/assets/photographers/EllieRoseWilkens.jpg new file mode 100644 index 00000000000..85b4e021200 Binary files /dev/null and b/assets/photographers/EllieRoseWilkens.jpg differ diff --git a/assets/photographers/MarcelNikolic.jpg b/assets/photographers/MarcelNikolic.jpg new file mode 100644 index 00000000000..a96a86ed8cb Binary files /dev/null and b/assets/photographers/MarcelNikolic.jpg differ diff --git a/assets/photographers/MimiKeel.jpg b/assets/photographers/MimiKeel.jpg new file mode 100644 index 00000000000..5df25f8502f Binary files /dev/null and b/assets/photographers/MimiKeel.jpg differ diff --git a/assets/photographers/NabeelBradford.jpg b/assets/photographers/NabeelBradford.jpg new file mode 100644 index 00000000000..acffb7a5fbb Binary files /dev/null and b/assets/photographers/NabeelBradford.jpg differ diff --git a/assets/photographers/RhodeDubois.jpg b/assets/photographers/RhodeDubois.jpg new file mode 100644 index 00000000000..17f4e8a4300 Binary files /dev/null and b/assets/photographers/RhodeDubois.jpg differ diff --git a/assets/photographers/TracyGalindo.jpg b/assets/photographers/TracyGalindo.jpg new file mode 100644 index 00000000000..306a6766fdb Binary files /dev/null and b/assets/photographers/TracyGalindo.jpg differ diff --git a/assets/video_preview.svg b/assets/video_preview.svg new file mode 100644 index 00000000000..27a8667e30e --- /dev/null +++ b/assets/video_preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/css/photographer.css b/css/photographer.css index 81854c023b9..0f7eb1b1435 100644 --- a/css/photographer.css +++ b/css/photographer.css @@ -1,39 +1,50 @@ #contact_modal { - display: none; -} - -.photograph-header { - background-color: #FAFAFA; - height: 300px; - margin: 0 100px; + display: none; + position: absolute; + width: 669px; + height: 900px; + top: 50%; + left: 50%; + bottom: 0; + background-color: #DB8876; + border-radius: 5px; + padding: 35px; + z-index: 3; + margin-top: -450px; + margin-left: -335px; } -.contact_button { - font-size: 20px; - font-weight: bold; - color: white; - padding: 11px; - width: 170px; - height: 70px; - border: none; - background-color: #901C1C; - border-radius: 5px; - cursor: pointer; +#contact_modal_overlay { + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 2; + align-items: center; + justify-content: center; } .modal { border-radius: 5px; background-color: #DB8876; - width: 50%; display: flex; + margin: auto; + width: auto; + height: auto; flex-direction: column; align-items: center; justify-content: space-between; padding: 35px; - margin: auto; + position: relative; + gap: 60px; } .modal header { + display: flex; + flex-direction: row; justify-content: space-between; width: 100%; } @@ -45,7 +56,154 @@ .modal header h2 { font-size: 64px; font-weight: normal; - text-align: center; +} + +.photograph_header { + background-color: #FAFAFA; + height: 300px; + margin: 0 100px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.text_container { + display: flex; + flex-direction: column; + gap: 19px; + padding-left: 50px; +} + +.photographer_main_title { + color: var(--secondary); + font-family: var(--photographer-main-title-font-family); + font-size: var(--photographer-main-title-font-size); + font-style: var(--photographer-main-title-font-style); + font-weight: var(--photographer-main-title-font-weight); + line-height: var(--photographer-main-title-line-height); +} + +.city_of_country_of { + color: var(--primary); + font-family: var(--city-of-country-of-font-family); + font-size: var(--city-of-country-of-font-size); + font-style: var(--city-of-country-of-font-style); + font-weight: var(--city-of-country-of-font-weight); + line-height: var(--city-of-country-of-line-height); +} + +.photographer_tagline { + color: var(--dark-grey); + font-family: var(--photographer-tagline-font-family); + font-size: var(--photographer-tagline-font-size); + font-style: var(--photographer-tagline-font-style); + font-weight: var(--photographer-tagline-font-weight); + line-height: var(--photographer-tagline-line-height); +} + +.img_wrapper { + height: 200px; + width: 200px; +} + +.img_wrapper img { + height: 100%; + width: 100%; + object-fit: cover; + border-radius: 50%; +} + +.filter { + display: flex; + gap: 25px; + align-items: center; + margin-left: 100px; +} + +.filter_title { + color: var(--black); + font-family: var(--photographer-filter-title-font-family); + font-size: var(--photographer-filter-title-font-size); + font-style: var(--photographer-filter-title-font-style); + font-weight: var(--photographer-filter-title-font-weight); + line-height: var(--photographer-filter-title-line-height); +} + +.dropdown { + position: relative; + display: inline-block; +} + +/* on cache le contenu initalement */ +.dropdown_content { + display: none; + position: absolute; + z-index: 1; +} +/* le contenu apparait au survol */ +.dropdown:hover .dropdown_content { + display: block; +} + +.dropdown_content.show { + display: block; +} + +.dropdown:hover .chevron { + transform: rotate(180deg); + transition: transform 300ms; +} + +.dropdown_btn { + font-size: 20px; + font-weight: bold; + color: white; + padding: 11px; + width: 170px; + height: 70px; + border: none; + background-color: #901C1C; + border-radius: 5px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + +} + +.dropdown_menu { + font-size: 20px; + font-weight: bold; + color: white; + padding: 11px; + width: 170px; + height: 70px; + border: none; + background-color: #901C1C; + border-radius: 5px; + cursor: pointer; + border-bottom: 1px solid white; + border-top: 1px solid white; +} + +.chevron { + width: 32px; + height: 32px; + color: white; +} + +.contact_button { + font-size: 20px; + font-weight: bold; + color: white; + padding: 11px; + width: 170px; + height: 70px; + border: none; + background-color: #901C1C; + border-radius: 5px; + cursor: pointer; } form { @@ -55,6 +213,10 @@ form { align-items: flex-start; } +form legend { + display: none; +} + form label { color: #312E2E; font-size: 36px; @@ -73,4 +235,159 @@ form input { height: 68px; border: none; border-radius: 5px; -} \ No newline at end of file + font-family: 'DM sans', sans-serif; + font-size: 24px; + font-weight: 400; + font-style: normal; + line-height: normal; + color: var(--black); +} + +fieldset { + border: none; +} + +textarea { + width: 100%; + height: 170px; +} + +.portfolio_container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 95px; + padding-top: 84px; + margin: 0 100px ; +} + +.media_container { + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 10px; +} + +.like_icon { + cursor: pointer; +} + +.media_wrapper { + width: 350px; + height: 300px; + background-color: transparent; + cursor: pointer; +} + +.media_itself { + width: 350px; + height: 300px; + object-fit: cover; +} + +.media_description { + display: flex; + justify-content: space-between; + align-items: center; + color: var(--primary); +} + +.media_title { + font-family: var(--media-title-font-family); + font-size: var(--media-title-font-size); + font-weight: var(--media-title-font-weight); + font-style: var(--media-title-font-style); + line-height: var(--media-title-line-height); + color: var(--primary); +} + +.sticky_banner { + display: flex; + position: fixed; + bottom: 0; + right: 0; + background-color: var(--secondary); + border-radius: 5px; + width: 376px; + height: 89px; + margin-right: 36px; + padding: 31px 21px; + box-sizing: border-box; + align-items: center; + justify-content: space-between; + font-family: var(--sticky-banner-font-family); + font-size: var(--sticky-banner-font-size); + font-weight: var(--sticky-banner-font-weight); + font-style: var(--sticky-banner-font-style); + line-height: var(--sticky-banner-line-height); + +} + +.total_likes_container { + display: flex; + gap: 3px; +} + +.like_container { + display: flex; + gap: 3px; + align-items: center; + justify-content: center; +} + +.nav_btn { + width: 96px; + height: 96px; + cursor: pointer; +} + +.lightbox { + background-color: #FAFAFA; + display: none; + position: fixed; + height: 100%; + width: 100%; + top: 0; + left: 0; + z-index: 10; + align-items: center; + justify-content: center; +} + +.media_viewer_container { + display: flex; + flex-direction: column; + gap: 12px; + align-items: start; +} + +.media_viewer_wrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.closing_lightbox_btn { + position: absolute; + top: 5%; + right: 5%; + cursor: pointer; +} + +.media_viewer_wrapper img, .media_viewer_wrapper video { + max-height: 90vh; + object-fit: contain; + width: 100%; + height: auto; +} + +.media_title_in_lightbox_container { + position: absolute; + bottom: 1%; +} + +.media_title_in_lightbox { + position: relative; +} + diff --git a/css/style.css b/css/style.css index e4dafd3521b..caa2aab2bbc 100644 --- a/css/style.css +++ b/css/style.css @@ -1,10 +1,81 @@ @import url("photographer.css"); -body { - font-family: "DM Sans", sans-serif; +:root { + --primary: #901C1C; + --secondary: #d3573c; + --black: #000000; + --light-black: #757575; + --dark-grey: #525252; + +/* ------------------ INDEX PAGE -------------------------------- */ + + --main-title-font-family: 'DM sans', sans-serif; + --main-title-font-size: 36px; + --main-title-font-style: normal; + --main-title-font-weight: 400; + + --photographer-name-font-family: 'DM sans', sans-serif; + --photographer-name-font-size: 36px; + --photographer-name-font-style: normal; + --photographer-name-font-weight: 400; + + --city-country-font-family: 'DM sans', sans-serif; + --city-country-font-size: 13px; + --city-country-font-style: normal; + --city-country-font-weight: 400; + + --tagline-font-family: 'DM sans', sans-serif; + --tagline-font-size: 10px; + --tagline-font-style: normal; + --tagline-font-weight: 400; + + --price-font-family: 'DM sans'; + --price-font-size: 9px; + --price-font-style: normal; + --price-font-weight: 400; + +/* ------------------ PHOTOGRAPHER PAGE -------------------------------- */ + + --photographer-main-title-font-family: 'DM sans', sans-serif; + --photographer-main-title-font-size: 64px; + --photographer-main-title-font-style: normal; + --photographer-main-title-font-weight: 400; + + --city-of-country-of-font-family: 'DM sans', sans-serif; + --city-of-country-of-font-size: 24px; + --city-of-country-of-font-style: normal; + --city-of-country-of-font-weight: 400; + + --media-title-font-family: 'DM sans', sans-serif; + --media-title-font-size: 21px; + --media-title-font-style: normal; + --media-title-font-weight: 400; + + --photographer-tagline-font-family: 'DM sans', sans-serif; + --photographer-tagline-font-size: 18px; + --photographer-tagline-font-style: normal; + --photographer-tagline-font-weight: 400; + + --photographer-filter-title-font-family: 'DM sans', sans-serif; + --photographer-filter-title-font-size: 18px; + --photographer-filter-title-font-style: normal; + --photographer-filter-title-font-weight: 700; + + --sticky-banner-font-family : 'DM sans', sans-serif; + --sticky-banner-font-size: 24px; + --sticky-banner-font-style : normal; + --sticky-banner-font-weight: 500; +} + + +* { margin: 0; + padding: 0; } +body { + font-family: "DM Sans", sans-serif; +} header { display: flex; @@ -14,8 +85,12 @@ header { height: 90px; } -h1 { - color: #901C1C; +.main_title { + color: var(--primary); + font-family: var(--main-title-font-family); + font-size: var(--main-title-font-size); + font-style: var(--main-title-font-style); + font-weight: var(--main-title-font-weight); margin-right: 100px; } @@ -40,11 +115,62 @@ h1 { } .photographer_section article h2 { - color: #D3573C; - font-size: 36px; + color: var(--secondary); + font-family: var(--main-title-font-family); + font-size: var(--main-title-font-size); + font-style: var(--main-title-font-style); + font-weight: var(--main-title-font-weight); } -.photographer_section article img { +.portrait_wrapper { height: 200px; width: 200px; -} \ No newline at end of file +} + +.photographer_section article img { + height: 100%; + width: 100%; + object-fit: cover; + border-radius: 50%; +} + +.section_under_name { + display: flex; + flex-direction: column; + gap: 3px; + justify-content: center; + align-items: center; +} + +.city_country { + color: var(--primary); + font-family: var(--city-country-font-family); + font-size: var(--city-country-font-size); + font-style: var(--city-country-font-style); + font-weight: var(--city-country-font-weight); +} + +.tagline { + color: var(--black); + font-family: var(--tagline-font-family); + font-size: var(--tagline-font-size); + font-style: var(--tagline-font-style); + font-weight: var(--tagline-font-weight); +} + +.price { + text-align: center; + color: var(--light-black); + font-family: var(--price-font-family); + font-size: var(--price-font-size); + font-style: var(--price-font-style); + font-weight: var(--price-font-weight); +} + +footer { + display: flex; + align-items: center; + justify-content: center; + padding-top: 200px; +} + diff --git a/index.html b/index.html index 7927da414a0..8cd38a1db58 100644 --- a/index.html +++ b/index.html @@ -1,21 +1,33 @@ - - - - - - Fisheye - - -
- -

Nos photographes

-
-
-
-
- - - - + + + + + + + Fisheye + + + +
+ +

Nos photographes

+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..131a02d5e75 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1135 @@ +{ + "name": "front-end-fisheye", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "front-end-fisheye", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "eslint": "^8.55.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000000..7b56ddfb93d --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "front-end-fisheye", + "version": "1.0.0", + "description": "## Démarrer le projet", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "eslint": "^8.55.0" + } +} diff --git a/photographer.html b/photographer.html index d85fc10fe89..bf58a2ee5f5 100644 --- a/photographer.html +++ b/photographer.html @@ -1,37 +1,110 @@ - - - - - - - Fisheye - photographe - - -
- -
-
-
- + + + + + + + + + Fisheye - photographe + + + +
+ +
+ +
+
+
+

+

+

-
-
- -
- - - + +
+ +
+
+
+

Trier par

+ +
+
+ +
+
+ + +
+ +
+ +
+
+

+ icone coeur +
+

+
+ + + + + + + + + + + + diff --git a/scripts/Factory/MediaFactory.js b/scripts/Factory/MediaFactory.js new file mode 100644 index 00000000000..0f867493e2a --- /dev/null +++ b/scripts/Factory/MediaFactory.js @@ -0,0 +1,44 @@ +import Media from '../models/Media.js' + + +// Création de la MediaFactory avec la logique image / vidéo + +export default class MediaFactory { + + static createFromJson(data) { + const { title, image, video } = data + const type = image === undefined ? 'video' : 'image' + const src = image === undefined ? video : image + return new Media(title, type, src) + } + + static createDomElementFromMedia(media, photographerName ,isPreview = false, index = 0) { + + let elementType = media.type === 'image' ? 'img' : 'video' + if (isPreview) { + elementType = 'img' + } + + let src = media.src + if (media.type === 'video' && isPreview) { + src = 'video_preview.svg' + } + + const element = document.createElement(elementType) + const encodedPhotographerName = encodeURIComponent(photographerName); + + element.setAttribute('src', `assets/images/${encodedPhotographerName}/` + src) + element.setAttribute('alt', media.title) + element.setAttribute('tabindex', '0') + element.setAttribute('class', 'media_itself') + element.setAttribute('data-index', index) + element.setAttribute('data-type', media.type) + element.setAttribute('data-original-src', `assets/images/${encodedPhotographerName}/` + media.src) + element.setAttribute('data-title', media.title) + return element + } +} + + + + diff --git a/scripts/Factory/UserCardFactory.js b/scripts/Factory/UserCardFactory.js new file mode 100644 index 00000000000..0294920917b --- /dev/null +++ b/scripts/Factory/UserCardFactory.js @@ -0,0 +1,10 @@ + + +export default class UserCardFactory { + + static createFromPhotographer(photographerData) { + + const { name, id, city, country, tagline, price, portrait } = photographerData + return new UserCard(name, id, city, country, tagline, price, portrait).create() + } +} diff --git a/scripts/Repository/Repository.js b/scripts/Repository/Repository.js new file mode 100644 index 00000000000..d3d23d2f1f6 --- /dev/null +++ b/scripts/Repository/Repository.js @@ -0,0 +1,23 @@ + +export async function getPhotographers() { + const response = await fetch('./data/photographers.json') + const data = await response.json() + return data.photographers +} + +export async function getMedias() { + const response = await fetch('./data/photographers.json') + const data = await response.json() + return data.media +} + +export async function getPhotographer(id) { + const photographers = await getPhotographers() + return photographers.find(p => p.id == id) +} + +export async function getMediaByPhotographer(photographerId) { + const medias = await getMedias() + return medias.filter(m => m.photographerId == photographerId) +} + diff --git a/scripts/models/Media.js b/scripts/models/Media.js new file mode 100644 index 00000000000..6be051d41e8 --- /dev/null +++ b/scripts/models/Media.js @@ -0,0 +1,12 @@ +/* Classe Media pour représenter une image ou une vidéo + default : pour exporter uniquement la classe dans le document */ + +export default class Media { + + constructor(title, type, src) { + this.title = title + this.type = type + this.src = src + } + +} diff --git a/scripts/pages/index.js b/scripts/pages/index.js index 42895574b83..b6544dbe6b0 100644 --- a/scripts/pages/index.js +++ b/scripts/pages/index.js @@ -1,46 +1,15 @@ - async function getPhotographers() { - // Ceci est un exemple de données pour avoir un affichage de photographes de test dès le démarrage du projet, - // mais il sera à remplacer avec une requête sur le fichier JSON en utilisant "fetch". - let photographers = [ - { - "name": "Ma data test", - "id": 1, - "city": "Paris", - "country": "France", - "tagline": "Ceci est ma data test", - "price": 400, - "portrait": "account.png" - }, - { - "name": "Autre data test", - "id": 2, - "city": "Londres", - "country": "UK", - "tagline": "Ceci est ma data test 2", - "price": 500, - "portrait": "account.png" - }, - ] - // et bien retourner le tableau photographers seulement une fois récupéré - return ({ - photographers: [...photographers, ...photographers, ...photographers]}) - } +import UserCardFactory from '../Factory/UserCardFactory.js' +import { getPhotographers } from '../Repository/Repository.js' - async function displayData(photographers) { - const photographersSection = document.querySelector(".photographer_section"); +async function displayData(photographers) { + const photographersSection = document.querySelector('.photographer_section') - photographers.forEach((photographer) => { - const photographerModel = photographerTemplate(photographer); - const userCardDOM = photographerModel.getUserCardDOM(); - photographersSection.appendChild(userCardDOM); - }); - } + photographers.forEach((photographer) => { - async function init() { - // Récupère les datas des photographes - const { photographers } = await getPhotographers(); - displayData(photographers); - } - - init(); - + const userCardDOM = UserCardFactory.createFromPhotographer(photographer) + photographersSection.appendChild(userCardDOM) + }) +} + +const photographers = await getPhotographers() +displayData(photographers) \ No newline at end of file diff --git a/scripts/pages/photographer.js b/scripts/pages/photographer.js index cee76db76f8..16b78bce7da 100644 --- a/scripts/pages/photographer.js +++ b/scripts/pages/photographer.js @@ -1 +1,40 @@ -//Mettre le code JavaScript lié à la page photographer.html \ No newline at end of file +import { getPhotographer } from '../Repository/Repository.js' +import getIdFromUrl from '../utils/urlHelpers.js' + +async function loadPhotographerContent() { + + const filteredPhotographer = await getPhotographer(getIdFromUrl()) + + const { name, city, country, tagline, price } = filteredPhotographer + + const photographHeader = document.querySelector('.photograph_header') + const textContainer = document.querySelector('.text_container') + textContainer.style.order = '-1' + + const nameOf = document.querySelector('.photographer_main_title') + nameOf.textContent = name + const cityOfCountryOf = document.querySelector('.city_of_country_of') + const tagLineOf = document.querySelector('.photographer_tagline') + + const priceOf = document.createElement('p') + priceOf.textContent = price + + const portraitOf = document.querySelector('.portrait_of_photographer') + portraitOf.setAttribute('src', `assets/photographers/${name.replace(' ', '').replace('-', '')}.jpg`) + portraitOf.setAttribute('alt', 'portrait du photographe ' + `${name}`) + + cityOfCountryOf.textContent = city + ', ' + country + tagLineOf.textContent = tagline + + const imgWrapper = document.querySelector('.img_wrapper') + + photographHeader.appendChild(textContainer) + photographHeader.appendChild(imgWrapper) + textContainer.appendChild(nameOf) + textContainer.appendChild(cityOfCountryOf) + textContainer.appendChild(tagLineOf) + imgWrapper.appendChild(portraitOf) +} + +loadPhotographerContent() + diff --git a/scripts/services/Lightbox.js b/scripts/services/Lightbox.js new file mode 100644 index 00000000000..d521d17ac4e --- /dev/null +++ b/scripts/services/Lightbox.js @@ -0,0 +1,221 @@ +class Lightbox { + constructor(openersSelector, closeBtn, prevBtn, nextBtn, lightboxItself, mediaViewerWrapper) { + this.openersSelector = openersSelector + this.closeBtn = document.querySelector(closeBtn) + this.prevBtn = document.querySelector(prevBtn) + this.nextBtn = document.querySelector(nextBtn) + this.lightboxItself = document.querySelector(lightboxItself) + this.mediaViewerWrapper = document.querySelector(mediaViewerWrapper) + } + + openLightbox() { + document.addEventListener('click', (event) => { + const opener = event.target.closest(this.openersSelector) + if (opener) { + this.currentMediaIndex = parseInt(opener.getAttribute('data-index')) + this.currentMediaType = opener.getAttribute('data-type') + this.currentMediaSrc = opener.getAttribute('data-original-src') + this.currentMediaTitle = opener.getAttribute('data-title') + this.showMedia() + this.lightboxItself.style.display = 'flex' + + this.focusedElementBeforeLightbox = document.activeElement + this.enableFocusTrap() + } + }) + + this.keydownListener = (event) => { + if (event.code === 'Space' && this.lightboxItself.style.display === 'flex') { + this.playVideoOnSpaceKey() + } + } + + document.addEventListener('keydown', this.keydownListener) + } + + openLightboxWithEnterKey() { + + document.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + const focusedElement = document.activeElement // si element en focus correspond au média : + if (focusedElement && focusedElement.matches(this.openersSelector)) { + + this.currentMediaIndex = parseInt(focusedElement.getAttribute('data-index')) + this.currentMediaType = focusedElement.getAttribute('data-type') + this.currentMediaSrc = focusedElement.getAttribute('data-original-src') + this.showMedia() + this.lightboxItself.style.display = 'flex' + }} + }) + } + + showMedia() { + + this.mediaViewerWrapper.innerHTML = '' // remise à zéro du contenu du media viewer + + if (this.currentMediaType === 'image') { + const img = document.createElement('img') + img.src = this.currentMediaSrc + this.mediaViewerWrapper.appendChild(img) + + const mediaTitle = document.querySelector('.media_title_in_lightbox') + img.title = this.currentMediaTitle + mediaTitle.textContent = img.title + + } else if (this.currentMediaType === 'video') { + const video = document.createElement('video') + video.src = this.currentMediaSrc + video.controls = true + this.mediaViewerWrapper.appendChild(video) + + const mediaTitle = document.querySelector('.media_title_in_lightbox') + video.title = this.currentMediaTitle + mediaTitle.textContent = video.title + } + } + + closeLightbox() { + + this.closeBtn.setAttribute('tabindex', '0') + this.closeBtn.addEventListener('click', () => { + this.lightboxItself.style.display = 'none' + document.removeEventListener('keydown', this.keydownListener) + }) + + // fermeture de la lightbox quand le focus est sur la croix et touche entrée pressée + this.closeBtn.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + this.lightboxItself.style.display = 'none' + document.removeEventListener('keydown', this.keydownListener) + } + }) + // fermeture de la lightbox en appuyant sur la touche échap + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape' && this.lightboxItself.style.display === 'flex') { + this.lightboxItself.style.display = 'none' + } + }) + + if (this.focusedElementBeforeLightbox) { + this.focusedElementBeforeLightbox.focus() + } + + this.disableFocusTrap() + } + + // permet au focus de rester dans la lightbox après ouverture + enableFocusTrap() { + this.focusTrapListener = (event) => { + if (this.lightboxItself.style.display === 'flex') { + + const focusableElements = this.lightboxItself.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])') + const firstFocusableElement = focusableElements[0] + const lastFocusableElement = focusableElements[focusableElements.length - 1] + + if (event.target === lastFocusableElement && event.key === 'Tab' && !event.shiftKey) { + event.preventDefault() + firstFocusableElement.focus() + } else if (event.target === firstFocusableElement && event.key === 'Tab' && event.shiftKey) { + event.preventDefault() + lastFocusableElement.focus() + } + } + } + + document.addEventListener('keydown', this.focusTrapListener) + } + + // permet au focus de se décloisonner de la lightbox à la fermeture de celle ci + disableFocusTrap() { + document.removeEventListener('keydown', this.focusTrapListener) + } + + + showPreviousMedia() { + + this.prevBtn.setAttribute('tabindex', '0') + this.prevBtn.addEventListener('click', () => { + if (this.currentMediaIndex > 0) { + this.currentMediaIndex-- + this.changeMedia() + } + }) + + this.prevBtn.addEventListener('keydown', (event) => { + if (event.key === 'Enter' && this.currentMediaIndex > 0) { + this.currentMediaIndex-- + this.changeMedia() + } + }) + + document.addEventListener('keydown', (event) => { + if (event.key === 'ArrowLeft' && this.lightboxItself.style.display === 'flex' && this.currentMediaIndex > 0) { + this.currentMediaIndex-- + this.changeMedia() + } + }) + } + + showNextMedia() { + + this.nextBtn.setAttribute('tabindex', '0') + this.nextBtn.addEventListener('click', () => { + if (this.currentMediaIndex < this.countTotalMediaItems() - 1) { + this.currentMediaIndex++ + this.changeMedia() + } + }) + + this.nextBtn.addEventListener('keydown', (event) => { + if (event.key === 'Enter' && this.currentMediaIndex < this.countTotalMediaItems() - 1) { + this.currentMediaIndex++ + this.changeMedia() + } + }) + + document.addEventListener('keydown', (event) => { + if (event.key === 'ArrowRight' && this.lightboxItself.style.display === 'flex' && this.currentMediaIndex < this.countTotalMediaItems() - 1) { + this.currentMediaIndex++ + this.changeMedia() + } + }) + } + + countTotalMediaItems() { + this.totalMediaItems = document.querySelectorAll(this.openersSelector).length + return this.totalMediaItems + } + + changeMedia() { + if (this.currentMediaIndex >= 0 && this.currentMediaIndex < this.countTotalMediaItems()) { + + let currentMedia = document.querySelector('img[data-index=\'' + this.currentMediaIndex + '\']') + this.currentMediaSrc = currentMedia.getAttribute('data-original-src') + this.currentMediaType = currentMedia.getAttribute('data-type') + this.currentMediaTitle = currentMedia.getAttribute('data-title') + this.showMedia() + } + } + + playVideoOnSpaceKey() { + if (this.currentMediaType === 'video') { + const video = this.mediaViewerWrapper.querySelector('video') + if (video) { + if (video.paused) { + video.play() + } else { + video.pause() + } + } + } + } +} + +const newLightbox = new Lightbox('.media_wrapper img', '.closing_lightbox_btn', '.prev_btn', '.next_btn', '.lightbox', '.media_viewer_wrapper') +newLightbox.openLightbox() +newLightbox.openLightboxWithEnterKey() +newLightbox.closeLightbox() +newLightbox.showMedia() +newLightbox.showPreviousMedia() +newLightbox.showNextMedia() +newLightbox.playVideoOnSpaceKey() diff --git a/scripts/services/Modal.js b/scripts/services/Modal.js new file mode 100644 index 00000000000..26e4f35e9c3 --- /dev/null +++ b/scripts/services/Modal.js @@ -0,0 +1,113 @@ +import { getPhotographer } from '../Repository/Repository.js' +import getIdFromUrl from '../utils/urlHelpers.js' + +class Modal { + + constructor(modal, modalOverlay, form, contactBtn, submitBtn, closeBtn) { + + this.modal = document.querySelector(modal) + this.modalOverlay = document.querySelector(modalOverlay) + this.form = document.querySelector(form) + this.contactBtn = document.querySelector(contactBtn) + this.submitBtn = document.querySelector(submitBtn) + this.closeBtn = document.querySelector(closeBtn) + } + + openModal() { + this.contactBtn.addEventListener('click', () => { + this.modal.style.display = 'block' + this.modalOverlay.style.display = 'block' + + const mainElements = document.querySelectorAll('main, main *') + if (mainElements) { + mainElements.forEach(element => { + element.setAttribute('aria-hidden', 'true') + element.setAttribute('tabindex', '-1') + }) + } + + const headerElement = document.querySelector('header') + if (headerElement) { + headerElement.setAttribute('aria-hidden', 'true') + headerElement.setAttribute('tabindex', '-1') + } + }) + } + + closeModal() { + this.modal.style.display = 'none' + this.modalOverlay.style.display = 'none' + + const mainElements = document.querySelectorAll('main, main *') + mainElements.forEach(element => { + element.removeAttribute('aria-hidden') + }) + + const headerElement = document.querySelector('header') + if (headerElement) { + headerElement.removeAttribute('aria-hidden') + } + } + + closeModalWithClick() { + this.closeBtn.addEventListener('click', () => { + this.closeModal() + }) + } + + closeModalWithEsc() { + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + this.closeModal() + } + }) + } + + closeModalWithEnter() { + this.closeBtn.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + this.closeModal() + } + }) + } + + getFormValues() { + const formValues = {} + for (let i = 0; i < this.form.elements.length; i++) { + const element = this.form.elements[i] + formValues[element.name] = element.value + } + return formValues + } + + getLogForm() { + this.form.addEventListener('submit', (event) => { + event.preventDefault() + console.log(this.getFormValues()) + this.modal.style.display = 'none' + this.modalOverlay.style.display = 'none' + }) + } + + init() { + this.openModal() + this.closeModalWithClick() + this.closeModalWithEnter() + this.closeModalWithEsc() + this.getFormValues() + this.getLogForm() + } +} + +const newModal = new Modal('#contact_modal', '#contact_modal_overlay', 'form', '.contact_button', '.submit_button', '#close_button') +newModal.init() + +async function addNameToModal() { + const photographer = await getPhotographer(getIdFromUrl()) + const nameAdded = photographer.name + const nameInModal = document.querySelector('.name_in_modal') + nameInModal.textContent = 'Contactez-moi ' + `${nameAdded}` + nameInModal.setAttribute('aria-label', 'Formulaire de contact pour' + `${nameAdded}`) +} + +addNameToModal() diff --git a/scripts/templates/mediaCreation.js b/scripts/templates/mediaCreation.js new file mode 100644 index 00000000000..4b355350b37 --- /dev/null +++ b/scripts/templates/mediaCreation.js @@ -0,0 +1,175 @@ +import { getMediaByPhotographer, getPhotographer } from '../Repository/Repository.js' +import MediaFactory from '../Factory/MediaFactory.js' +import getIdFromUrl from '../utils/urlHelpers.js' + +// fonction de tri des médias +const likesBtn = document.querySelector('.like_btn') +const dateBtn = document.querySelector('.date_btn') +const titleBtn = document.querySelector('.title_btn') + +likesBtn.addEventListener('click', () => { + getFilteredMedia('likes') +}) +dateBtn.addEventListener('click', () => { + getFilteredMedia('date') +}) +titleBtn.addEventListener('click', () => { + getFilteredMedia('title') +}) + +// sortir les fonctions dans les fonctions + +async function getFilteredMedia(selectedButton) { + const photographerId = getIdFromUrl() + const filteredMedia = await getMediaByPhotographer(photographerId) + + switch (selectedButton) { + case 'likes': + filteredMedia.sort((a, b) => b.likes - a.likes) + break + case 'date': + filteredMedia.sort((a, b) => new Date(b.date) - new Date(a.date)) + break + case 'title': + filteredMedia.sort((a, b) => a.title.localeCompare(b.title)) + break + default: + break + } + + const portfolioContainer = document.querySelector('.portfolio_container') + portfolioContainer.innerHTML = '' + + + const photographer = await getPhotographer(photographerId) + const photographerName = photographer.name + const photographerPrice = photographer.price + + const priceADay = document.querySelector('.price_a_day') + priceADay.textContent = `${photographerPrice}€ / jour` + + + filteredMedia.forEach((mediaItem, index) => { + const mediaObject = MediaFactory.createFromJson(mediaItem) + const mediaDomElement = MediaFactory.createDomElementFromMedia(mediaObject, photographerName, true, index, mediaItem.title) // on passe l'index à l'élement + + // Création de la structure pour media_description et likes + const mediaContainer = document.createElement('article') + mediaContainer.setAttribute('class', 'media_container') + + const mediaWrapper = document.createElement('div') + mediaWrapper.setAttribute('class', 'media_wrapper') + + const mediaDescription = document.createElement('section') + mediaDescription.setAttribute('class', 'media_description') + + const mediaTitle = document.createElement('h3') + mediaTitle.setAttribute('class', 'media_title') + mediaTitle.textContent = mediaItem.title + + + const likeContainer = document.createElement('div') + likeContainer.setAttribute('class', 'like_container') + + const numberOfLikes = document.createElement('p') + numberOfLikes.setAttribute('class', 'number_of_likes') + numberOfLikes.setAttribute('tabindex', '0') + numberOfLikes.textContent = mediaItem.likes + + const likeIcon = document.createElement('img') + likeIcon.setAttribute('class', 'like_icon') + likeIcon.setAttribute('alt', 'coeur') + likeIcon.setAttribute('tabindex', '0') + likeIcon.setAttribute('src', 'assets/heart.svg') + + // On rajoute tous les nouveaux élements au DOM + portfolioContainer.appendChild(mediaContainer) + mediaContainer.appendChild(mediaWrapper) + mediaWrapper.appendChild(mediaDomElement) + mediaContainer.appendChild(mediaDescription) + mediaDescription.appendChild(mediaTitle) + mediaDescription.appendChild(likeContainer) + likeContainer.appendChild(numberOfLikes) + likeContainer.appendChild(likeIcon) + }) + + function incrementLike() { + const likeIcons = document.querySelectorAll('.like_icon') + + likeIcons.forEach(likeIcon => { + likeIcon.addEventListener('click', () => incrementLikesOnClick(likeIcon)) + + likeIcon.addEventListener('keydown', (event) => { + if (event.key === 'Enter') { + incrementLikesOnEnter(event, likeIcon) + } + }) + }) + } + + function incrementLikesOnClick(likeIcon) { + const likeContainer = likeIcon.closest('.like_container') + const numberOfLikesElement = likeContainer.querySelector('.number_of_likes') + + if (!likeIcon.classList.contains('liked')) { + let likes = parseInt(numberOfLikesElement.textContent) + numberOfLikesElement.textContent = likes + 1 + likeIcon.classList.add('liked') + incrementTotalOfLikes() + } + } + + function incrementLikesOnEnter(event, likeIcon) { + event.preventDefault() + incrementLikesOnClick(likeIcon) + } + + incrementLike() + + function incrementTotalOfLikes() { + const totalLikesNumber = document.querySelector('.total_likes_number') + const likesElements = document.querySelectorAll('.number_of_likes') + + let totalLikes = 0 + likesElements.forEach(likesElement => { + totalLikes += parseInt(likesElement.textContent) + }) + + totalLikesNumber.textContent = totalLikes + } + incrementTotalOfLikes() +} + +getFilteredMedia() + + +// fonction pour modifier le dropdown menu au clic + +document.addEventListener('DOMContentLoaded', function () { + const dropdownContent = document.querySelector('.dropdown_content') + const selectedItem = document.getElementById('selected_item') + const selectedItemText = selectedItem.childNodes[0] + const dropdownBtn = document.querySelector('.dropdown_btn') + + function toggleDropdown() { + console.log('function') + // toggle ajoute une classe si elle n'existe pas et la supprime si elle existe + dropdownContent.classList.toggle('show') + } + + dropdownContent.addEventListener('click', function (e) { + if (e.target.classList.contains('dropdown_menu')) { + // l'item cliqué remonte en haut de la liste des enfants + dropdownContent.insertBefore(e.target, dropdownContent.firstChild) + + // mise à jour du texte seulement (pour conserver l'icone) + selectedItemText.nodeValue = e.target.textContent + } + }) + + dropdownBtn.addEventListener('keydown', function(e) { + if (e.key === 'Enter' || e.keyCode === 13) { + toggleDropdown() + } + }) +}) diff --git a/scripts/templates/photographer.js b/scripts/templates/photographer.js index f177ca1a8a7..543a8d617d4 100644 --- a/scripts/templates/photographer.js +++ b/scripts/templates/photographer.js @@ -1,17 +1,90 @@ -function photographerTemplate(data) { - const { name, portrait } = data; - - const picture = `assets/photographers/${portrait}`; - - function getUserCardDOM() { - const article = document.createElement( 'article' ); - const img = document.createElement( 'img' ); - img.setAttribute("src", picture) - const h2 = document.createElement( 'h2' ); - h2.textContent = name; - article.appendChild(img); - article.appendChild(h2); - return (article); - } - return { name, picture, getUserCardDOM } -} \ No newline at end of file +class UserCard { + constructor(name, id, city, country, tagline, price, portrait) { + + this.name = name + this._id = id + this.city = city + this.country = country + this.tagline = tagline + this.price = price + this.portrait = portrait + } + + get id() { + return this._id + } + + createLink() { + const linkTo = document.createElement('a') + linkTo.setAttribute('href', 'photographer.html?id=' + this._id) // récuperer l'id dans l'url pour le searchParams + linkTo.classList.add('link_to') + return linkTo + } + + createImageElement() { + const portraitWrapper = document.createElement('div') + portraitWrapper.classList.add('portrait_wrapper') + portraitWrapper.setAttribute('role', 'presentation') + // portraitWrapper.setAttribute('tabindex', '0') + portraitWrapper.setAttribute('id', this.id) + + const img = document.createElement('img') + const picture = `assets/photographers/${this.portrait}` + img.setAttribute('src', picture) + img.setAttribute('alt', 'photo de profil du Photographe ' + this.name) + + portraitWrapper.appendChild(img) + return portraitWrapper + } + + createTitleElement() { + const h2 = document.createElement('h2') + h2.textContent = this.name + return h2 + } + + createCityCountryElement() { + const span = document.createElement('span') + span.classList.add('city_country') + span.textContent = this.city + ', ' + this.country + return span + } + + createTagLineElement() { + const p = document.createElement('p') + p.classList.add('tagline') + p.textContent = this.tagline + return p + } + + createPriceElement() { + const p2 = document.createElement('p') + p2.classList.add('price') + p2.textContent = this.price + '€/jour' + return p2 + } + + create() { + const article = document.createElement('article') + const section = document.createElement('section') + section.classList.add('section_under_name') + + const portraitWrapper = this.createImageElement() + const h2 = this.createTitleElement() + const span = this.createCityCountryElement() + const p = this.createTagLineElement() + const p2 = this.createPriceElement() + const linkTo = this.createLink() + + article.appendChild(linkTo) + linkTo.appendChild(portraitWrapper) + article.appendChild(h2) + article.appendChild(section) + section.appendChild(span) + section.appendChild(p) + section.appendChild(p2) + return article + } + +} + diff --git a/scripts/utils/contactForm.js b/scripts/utils/contactForm.js deleted file mode 100644 index 9180380082c..00000000000 --- a/scripts/utils/contactForm.js +++ /dev/null @@ -1,9 +0,0 @@ -function displayModal() { - const modal = document.getElementById("contact_modal"); - modal.style.display = "block"; -} - -function closeModal() { - const modal = document.getElementById("contact_modal"); - modal.style.display = "none"; -} diff --git a/scripts/utils/urlHelpers.js b/scripts/utils/urlHelpers.js new file mode 100644 index 00000000000..1a754783e14 --- /dev/null +++ b/scripts/utils/urlHelpers.js @@ -0,0 +1,8 @@ + +// récuperer l'id du photographe depuis l'URL + +export default function getIdFromUrl() { + const idOfPhotographer = new URLSearchParams(window.location.search).get('id') + return idOfPhotographer +} +