From 592fd04f1f7160e7209bafd2364a5f68f2d4da19 Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:25:21 +0530 Subject: [PATCH 1/6] Create index.html --- MovieBase/index.html | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 MovieBase/index.html diff --git a/MovieBase/index.html b/MovieBase/index.html new file mode 100644 index 00000000..c3beed9d --- /dev/null +++ b/MovieBase/index.html @@ -0,0 +1,47 @@ + + + + + + Movie App + + + +
+

Movie Information

+ + +
+ + +
+ + +
+ + + + +
+ + +
+ + + +
+ + + + From 11704c188159a0e892a88e82f0f5cf7f583edcdb Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:25:51 +0530 Subject: [PATCH 2/6] Add files via upload --- MovieBase/README.md | 88 +++++++++++++++++++++++++ MovieBase/script.js | 156 ++++++++++++++++++++++++++++++++++++++++++++ MovieBase/style.css | 134 +++++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 MovieBase/README.md create mode 100644 MovieBase/script.js create mode 100644 MovieBase/style.css diff --git a/MovieBase/README.md b/MovieBase/README.md new file mode 100644 index 00000000..85ef135e --- /dev/null +++ b/MovieBase/README.md @@ -0,0 +1,88 @@ +
+

MovieBase

+ +
+ javascript + html5 + css3 + omdb-api +
+ +
+ An interactive movie discovery application that allows users to search for movies, filter results by genre, and sort movies by rating or votes using the OMDb API. +
+
+ +## Demo +[moviebase.webm](https://github.com/user-attachments/assets/003e6a54-ad0a-4c96-afa5-34389aa08877) + + + +## πŸ“‹ Table of Contents + +1. πŸ€– [Introduction](#introduction) +2. βš™οΈ [Tech Stack](#tech-stack) +3. πŸ”‹ [Features](#features) +4. 🀸 [Quick Start](#quick-start) +5. πŸ•ΈοΈ [Usage](#usage) + +## πŸ€– Introduction + +The **MovieBase** app is a user-friendly movie discovery platform that lets users search for movies and see essential details like rating, votes, genre, and plot. Users can filter results by genre, and sort movies by highest/lowest rating or most/least votes, all while fetching data from the OMDb API. + +## βš™οΈ Tech Stack + +- JavaScript +- HTML5 +- CSS3 +- OMDb API + +## πŸ”‹ Features + +πŸ‘‰ **Search for Movies**: Enter the name of any movie to fetch relevant results. + +πŸ‘‰ **Filter by Genre**: Filter the search results by selecting a specific genre from the dropdown menu. + +πŸ‘‰ **Sort Movies**: Sort the search results by highest rating, lowest rating, most votes, or least votes. + +πŸ‘‰ **Movie Details**: View essential details for each movie, including rating, total votes, genre, plot, and cast. + +πŸ‘‰ **Pagination**: Navigate through the results using "Previous" and "Next" buttons for pagination. + +## 🀸 Quick Start + +Follow these steps to set up the MovieBase app locally on your machine. + +### **Prerequisites** + +Make sure you have the following: + +- A modern web browser (Google Chrome, Firefox, etc.) +- API Key from OMDb API + +### **Cloning the Repository** + +```bash +git clone https://github.com/YourUsername/MovieBase.git +cd MovieBase +``` + + +Getting Your API Key + +- Go to the OMDb API website and sign up for an API key. +- Replace 'YOUR_API_KEY' in the script.js file with your actual API key. + +Running the Application +- Open the index.html file in your browser. +- Enter a movie title and press the "Search" button to display the movie data. +## πŸ•ΈοΈ Usage +**Search for a Movie**: Type the name of the movie in the search bar and press the "Search" button to view the movie details. + +**Filter by Genre**: Select a genre from the dropdown to filter the results by a specific genre. + +**Sort Movies**: Choose a sorting option (highest rating, lowest rating, most votes, or least votes) to re-arrange the movies based on that criteria. + +**View Movie Details**: For each movie, you can see the rating, total votes, genre, plot, and cast information. + +**Pagination**: Use the "Previous" and "Next" buttons to navigate through the paginated search results. diff --git a/MovieBase/script.js b/MovieBase/script.js new file mode 100644 index 00000000..1c6d9b02 --- /dev/null +++ b/MovieBase/script.js @@ -0,0 +1,156 @@ +let currentPage = 1; +let totalResults = 0; +let allMovies = []; +let filteredMovies = []; +const apiKey = 'xxxxx'; // Your OMDb API Key + +document.getElementById('search-button').addEventListener('click', () => { + currentPage = 1; + fetchMovies(currentPage); +}); + +document.getElementById('next-button').addEventListener('click', () => { + if (currentPage * 10 < totalResults) { + currentPage++; + displayMovieList(filteredMovies.slice((currentPage - 1) * 10, currentPage * 10)); + updatePaginationButtons(); + } +}); + +document.getElementById('prev-button').addEventListener('click', () => { + if (currentPage > 1) { + currentPage--; + displayMovieList(filteredMovies.slice((currentPage - 1) * 10, currentPage * 10)); + updatePaginationButtons(); + } +}); + +document.getElementById('genre-filter').addEventListener('change', filterMovies); +document.getElementById('sort-options').addEventListener('change', sortMovies); + +function fetchMovies(page) { + const movieTitle = document.getElementById('movie-search').value; + const url = `http://www.omdbapi.com/?s=${movieTitle}&apikey=${apiKey}&page=${page}`; + + fetch(url) + .then(response => response.json()) + .then(data => { + if (data.Response === "True") { + totalResults = parseInt(data.totalResults); + allMovies = data.Search; + fetchAllMovieDetails(); + } else { + alert("No movies found!"); + } + }) + .catch(error => console.error('Error fetching data:', error)); +} + +function fetchAllMovieDetails() { + filteredMovies = []; + let promises = allMovies.map(movie => { + return fetch(`http://www.omdbapi.com/?i=${movie.imdbID}&apikey=${apiKey}`) + .then(response => response.json()) + .then(data => { + if (data.Response === "True") { + filteredMovies.push(data); + } + }); + }); + + Promise.all(promises).then(() => { + populateGenreFilter(); + sortMovies(); + }); +} + +function populateGenreFilter() { + const genreFilter = document.getElementById('genre-filter'); + let genres = new Set(); + + filteredMovies.forEach(movie => { + if (movie.Genre) { + movie.Genre.split(", ").forEach(genre => genres.add(genre)); + } + }); + + genreFilter.innerHTML = ''; + genres.forEach(genre => { + const option = document.createElement('option'); + option.value = genre; + option.innerText = genre; + genreFilter.appendChild(option); + }); +} + +function filterMovies() { + const genre = document.getElementById('genre-filter').value; + if (genre === "") { + filteredMovies = [...allMovies]; + } else { + filteredMovies = allMovies.filter(movie => movie.Genre.includes(genre)); + } + sortMovies(); +} + +function sortMovies() { + const sortOption = document.getElementById('sort-options').value; + if (sortOption === "highestRating") { + filteredMovies.sort((a, b) => parseFloat(b.imdbRating) - parseFloat(a.imdbRating)); + } else if (sortOption === "lowestRating") { + filteredMovies.sort((a, b) => parseFloat(a.imdbRating) - parseFloat(b.imdbRating)); + } else if (sortOption === "mostVotes") { + filteredMovies.sort((a, b) => parseInt(b.imdbVotes.replace(/,/g, '')) - parseInt(a.imdbVotes.replace(/,/g, ''))); + } else if (sortOption === "leastVotes") { + filteredMovies.sort((a, b) => parseInt(a.imdbVotes.replace(/,/g, '')) - parseInt(b.imdbVotes.replace(/,/g, ''))); + } + + displayMovieList(filteredMovies.slice((currentPage - 1) * 10, currentPage * 10)); + updatePaginationButtons(); +} + +function displayMovieList(movies) { + const movieList = document.getElementById('movie-list'); + movieList.innerHTML = ''; + + movies.forEach(movie => { + const movieItem = document.createElement('div'); + movieItem.classList.add('movie-item'); + movieItem.innerHTML = ` + ${movie.Title} Poster +
+

${movie.Title} (${movie.Year})

+
+

Rating: ${movie.imdbRating}

+

Total Votes: ${movie.imdbVotes}

+

Genre: ${movie.Genre}

+

Plot: ${movie.Plot}

+

Cast: ${movie.Actors}

+
+
+ `; + movieList.appendChild(movieItem); + }); + + // Lazy load the images + const lazyImages = document.querySelectorAll('img.lazy'); + lazyImages.forEach(image => loadImage(image)); +} + +function loadImage(image) { + const observer = new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + image.src = image.dataset.src; + image.classList.remove('lazy'); + observer.unobserve(image); + } + }); + }); + observer.observe(image); +} + +function updatePaginationButtons() { + document.getElementById('prev-button').disabled = currentPage === 1; + document.getElementById('next-button').disabled = currentPage * 10 >= filteredMovies.length; +} diff --git a/MovieBase/style.css b/MovieBase/style.css new file mode 100644 index 00000000..91b2c485 --- /dev/null +++ b/MovieBase/style.css @@ -0,0 +1,134 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + margin: 0; + padding: 0; +} + +.container { + width: 60%; + margin: auto; + padding: 20px; +} + +h1 { + text-align: center; +} + +.search-container { + display: flex; + justify-content: center; + margin-bottom: 20px; +} + +.filter-sort-container { + display: flex; + justify-content: space-between; + margin-bottom: 20px; +} + +#movie-search { + width: 70%; + padding: 10px; + border-radius: 5px; + border: 1px solid #ccc; + margin-right: 10px; +} + +#search-button { + padding: 10px 20px; + background-color: #007BFF; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +#genre-filter, #sort-options { + padding: 10px; + border-radius: 5px; + border: 1px solid #ccc; +} + +#movie-details { + display: flex; + gap: 20px; +} + +#poster { + width: 200px; + height: 300px; + object-fit: cover; + display: none; +} + +.movie-info { + max-width: 500px; +} + +p { + margin: 5px 0; +} + +.pagination { + display: flex; + justify-content: center; + margin-top: 20px; +} + +button { + padding: 10px 20px; + background-color: #007BFF; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + margin: 0 10px; +} + +button:disabled { + background-color: #cccccc; + cursor: not-allowed; +} + +.movie-item { + display: flex; + align-items: flex-start; + margin-bottom: 20px; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + background-color: #fff; + width: 100%; +} + +.movie-item img { + width: 150px; + margin-right: 20px; +} + +.movie-content { + display: flex; + flex-direction: column; +} + +.movie-title { + font-size: 1.5em; + margin-bottom: 10px; +} + +.movie-details { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.movie-details p { + margin: 5px 0; + font-size: 0.9em; +} + +.movie-item h3 { + margin: 0 0 10px 0; + font-size: 1.2em; +} From 63ecbde93ddf2c77c3e276cd7a543825305180ca Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:28:38 +0530 Subject: [PATCH 3/6] Create popup.html --- DarkMode Chrome Extension/popup.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 DarkMode Chrome Extension/popup.html diff --git a/DarkMode Chrome Extension/popup.html b/DarkMode Chrome Extension/popup.html new file mode 100644 index 00000000..cec654f5 --- /dev/null +++ b/DarkMode Chrome Extension/popup.html @@ -0,0 +1,14 @@ + + + + Dark Mode Toggle + + + +
+ + +
+ + + From 9322667f9d3182b1da8e81a46d2e0ed7e505fc82 Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:29:09 +0530 Subject: [PATCH 4/6] Add files via upload --- DarkMode Chrome Extension/README.md | 78 +++++++++++++++++++++++++ DarkMode Chrome Extension/background.js | 10 ++++ DarkMode Chrome Extension/content.js | 27 +++++++++ DarkMode Chrome Extension/manifest.json | 34 +++++++++++ DarkMode Chrome Extension/popup.js | 22 +++++++ DarkMode Chrome Extension/styles.css | 15 +++++ 6 files changed, 186 insertions(+) create mode 100644 DarkMode Chrome Extension/README.md create mode 100644 DarkMode Chrome Extension/background.js create mode 100644 DarkMode Chrome Extension/content.js create mode 100644 DarkMode Chrome Extension/manifest.json create mode 100644 DarkMode Chrome Extension/popup.js create mode 100644 DarkMode Chrome Extension/styles.css diff --git a/DarkMode Chrome Extension/README.md b/DarkMode Chrome Extension/README.md new file mode 100644 index 00000000..04a1b4f7 --- /dev/null +++ b/DarkMode Chrome Extension/README.md @@ -0,0 +1,78 @@ +
+

Dark Mode for Websites

+ +
+ javascript + html5 + css3 + chrome-extensions +
+ +
+ A simple and efficient Chrome extension that enables dark mode for any website. This extension inverts the colors of web pages to provide a more comfortable viewing experience in low-light environments. +
+
+ +## πŸ“‹ Table of Contents + +1. πŸ€– [Introduction](#introduction) +2. βš™οΈ [Tech Stack](#tech-stack) +3. πŸ”‹ [Features](#features) +4. 🀸 [Quick Start](#quick-start) +5. πŸ•ΈοΈ [Usage](#usage) + +## πŸ€– Introduction + +The **Dark Mode for Websites** Chrome extension is designed to make browsing more comfortable by applying a dark theme to any website. Whether you're working late at night or simply prefer a darker interface, this extension inverts the colors of web pages to reduce eye strain and provide a pleasant browsing experience. + +## βš™οΈ Tech Stack + +- JavaScript +- HTML5 +- CSS3 +- Chrome Extensions API + +## πŸ”‹ Features + +πŸ‘‰ **Toggle Dark Mode**: Easily switch dark mode on or off for any website with a simple toggle. + +πŸ‘‰ **Dynamic Color Inversion**: Automatically inverts the colors of web pages while preserving the natural look of images and videos. + +πŸ‘‰ **Persistent Settings**: Remembers your dark mode preferences across different browsing sessions. + +πŸ‘‰ **Lightweight and Fast**: The extension is designed to be lightweight and runs efficiently without slowing down your browser. + +## 🀸 Quick Start + +Follow these steps to set up the Chrome extension locally on your machine. + +**Prerequisites** + +Make sure you have the following: + +- Google Chrome browser + +**Cloning the Repository** + +```bash +git clone https://github.com/Gobind147/Dark-Mode-Extension.git +cd Dark-Mode-Extension +``` + +Loading the Extension in Chrome + +1. Open Chrome and navigate to chrome://extensions/. +2. Enable "Developer mode" by toggling the switch in the upper right corner. +3. Click on "Load unpacked" and select the folder where you cloned the repository. +4. The extension should now appear in your list of installed extensions. + + +## πŸ•ΈοΈ Usage + +**Enable Dark Mode**: Click on the extension icon in the Chrome toolbar and toggle the switch to enable or disable dark mode for the current website. + +**Persistent Settings**: The extension will remember your settings for each site, so you don't have to re-enable dark mode every time. + +**Customize**: Modify the CSS and JavaScript in the content.js file to adjust the dark mode settings according to your preferences. + + diff --git a/DarkMode Chrome Extension/background.js b/DarkMode Chrome Extension/background.js new file mode 100644 index 00000000..2602de5a --- /dev/null +++ b/DarkMode Chrome Extension/background.js @@ -0,0 +1,10 @@ +chrome.runtime.onInstalled.addListener(() => { + if (chrome.storage) { + chrome.storage.sync.set({ darkMode: false }, () => { + console.log('Dark mode setting initialized to false.'); + }); + } else { + console.error('chrome.storage is not available'); + } + }); + \ No newline at end of file diff --git a/DarkMode Chrome Extension/content.js b/DarkMode Chrome Extension/content.js new file mode 100644 index 00000000..3ae87383 --- /dev/null +++ b/DarkMode Chrome Extension/content.js @@ -0,0 +1,27 @@ +// Function to toggle dark mode +function toggleDarkMode(isDarkMode) { + if (isDarkMode) { + document.documentElement.style.filter = 'invert(1) hue-rotate(180deg)'; + document.querySelectorAll('img, picture, video').forEach((element) => { + element.style.filter = 'invert(1) hue-rotate(180deg)'; + }); + } else { + document.documentElement.style.filter = ''; + document.querySelectorAll('img, picture, video').forEach((element) => { + element.style.filter = ''; + }); + } + } + + // Listen for changes in dark mode setting + chrome.storage.sync.get('darkMode', ({ darkMode }) => { + toggleDarkMode(darkMode); + }); + + // Listen for messages from popup + chrome.runtime.onMessage.addListener((message) => { + if (message.command === 'toggle-dark-mode') { + toggleDarkMode(message.darkMode); + } + }); + \ No newline at end of file diff --git a/DarkMode Chrome Extension/manifest.json b/DarkMode Chrome Extension/manifest.json new file mode 100644 index 00000000..48d798e4 --- /dev/null +++ b/DarkMode Chrome Extension/manifest.json @@ -0,0 +1,34 @@ +{ + "manifest_version": 3, + "name": "Dark Mode for Websites", + "version": "1.0", + "description": "Apply a dark mode to any website.", + "permissions": [ + "activeTab", + "scripting", + "storage" + ], + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + }, + "background": { + "service_worker": "background.js" + }, + "content_scripts": [ + { + "matches": [""], + "js": ["content.js"] + } + ], + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + } + \ No newline at end of file diff --git a/DarkMode Chrome Extension/popup.js b/DarkMode Chrome Extension/popup.js new file mode 100644 index 00000000..271c9ab1 --- /dev/null +++ b/DarkMode Chrome Extension/popup.js @@ -0,0 +1,22 @@ +document.addEventListener('DOMContentLoaded', () => { + const toggle = document.getElementById('dark-mode-toggle'); + + // Load the current state of dark mode + chrome.storage.sync.get('darkMode', ({ darkMode }) => { + toggle.checked = darkMode; + }); + + // Handle toggle change + toggle.addEventListener('change', () => { + const darkMode = toggle.checked; + chrome.storage.sync.set({ darkMode }); + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + chrome.scripting.executeScript({ + target: { tabId: tabs[0].id }, + files: ['content.js'], + }); + chrome.tabs.sendMessage(tabs[0].id, { command: 'toggle-dark-mode', darkMode }); + }); + }); + }); + \ No newline at end of file diff --git a/DarkMode Chrome Extension/styles.css b/DarkMode Chrome Extension/styles.css new file mode 100644 index 00000000..2a925d61 --- /dev/null +++ b/DarkMode Chrome Extension/styles.css @@ -0,0 +1,15 @@ +body { + font-family: Arial, sans-serif; + padding: 20px; + min-width: 150px; + } + + #toggle-container { + display: flex; + align-items: center; + } + + #dark-mode-toggle { + margin-left: 10px; + } + \ No newline at end of file From 8b70d0fe4d1921ffc1bd0effc239f3ebcc386b2d Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:30:55 +0530 Subject: [PATCH 5/6] Create app.html --- DarkMode Chrome Extension/icons/app.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 DarkMode Chrome Extension/icons/app.html diff --git a/DarkMode Chrome Extension/icons/app.html b/DarkMode Chrome Extension/icons/app.html new file mode 100644 index 00000000..fef83a9c --- /dev/null +++ b/DarkMode Chrome Extension/icons/app.html @@ -0,0 +1 @@ +// comment From 6b0d2654a6b7d23ad1036c820610833383ed3479 Mon Sep 17 00:00:00 2001 From: Gobind Kumar <93241765+Gobind147@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:31:14 +0530 Subject: [PATCH 6/6] Add files via upload --- DarkMode Chrome Extension/icons/icon128.png | Bin 0 -> 3014 bytes DarkMode Chrome Extension/icons/icon16.png | Bin 0 -> 951 bytes DarkMode Chrome Extension/icons/icon48.png | Bin 0 -> 3084 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 DarkMode Chrome Extension/icons/icon128.png create mode 100644 DarkMode Chrome Extension/icons/icon16.png create mode 100644 DarkMode Chrome Extension/icons/icon48.png diff --git a/DarkMode Chrome Extension/icons/icon128.png b/DarkMode Chrome Extension/icons/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..6deb0731a58653b70593b0c5d926aa21d075a062 GIT binary patch literal 3014 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 literal 0 HcmV?d00001 diff --git a/DarkMode Chrome Extension/icons/icon16.png b/DarkMode Chrome Extension/icons/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..62381dde2dd14fe531bf191dd26de95a8acfa829 GIT binary patch literal 951 zcmV;o14#UdP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L02y>eSaefwW^{L9 za%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00SpUL_t(IPi2#PXcSiz#(y)Djq7IfATdZ% zt1&A0sHI|RQNg5Y3fhO_t7wuc7K@MmQN_|&>K|fkS{kaTHIx)1k|wm)h#(4$6}3S^ z8jB>p+ZfHpV4mIVE0f)wx!yZbP+kk^dPw@KHS}tb3#!o+f@6=EYKL7f# zsQX~CsQ#lx1mZ&Y1|m*&_J^H({;q1rFSdxf6-$JiR!N24`CpLS#xvY_yM)#Ga|s4a zBBsTY{s5L`5sSs>?hO!=6Z!oS))dU;MnN$-f7auZTCJk;q~Lrl#lKy^3Y!dtM>x2D zGt(y}laN!)y?-B)pLLznS9>^CRnKrFg3IfnX3a8Kz5(5R_d0>u3rUn_X+|P_{wVLh zmBy~EQ)p{xz%z1(bsHuyXR0(drVMd8+@RDbt#0&oNw;&Q8L;omjWnG*z^rN65U{D* z?cuxaDbOFMATO6+DtA)0ceBG)8l}~x57I~*O?Dj_4iWVC5RXOWmn2|Irn4iBSag`+ zP%ozBjFxP*021QkvY@M7aVS4j&p*CF?l+e*{S7ZgUj;~Y$2oQ&i)(E?Y}xZO#HE{( zD}3!Jt!~c9Be}Jau>3#UijtX{$mvUuD642;{-XCV(&upehremMIl$NiDYT;wH>Ir+ zrPbsbMg6Km+6y;QUb>Ybzez~0F&K)Fk?O{_Z3c#9KgEZ}ErZU8$k!>}68Z+$6aT#%Fjj3YaGo4sdY}Gijt4E ziRyP2h#mWnhz@^L3`T{JhtEm%tT0upE?gjrOSU~z3Gvcp+Ff>t@eOsDZZE+Z^RTjW z99-{yNXngN+-8WLrR%BK`MFl$^k+U$9(FIp?dPI9o( ZfTx>Dr8)@pdG!DQ002ovPDHLkV1mJ7zS95z literal 0 HcmV?d00001 diff --git a/DarkMode Chrome Extension/icons/icon48.png b/DarkMode Chrome Extension/icons/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5ee3d750a1b746162c948edda72ddffdd5ca29 GIT binary patch literal 3084 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