// ==UserScript==
// @name Coursera Transcript to AI: Video Summarizer 🎬📝
// @namespace thecolourofmadness
// @version 1.5
// @description Adds buttons to copy Coursera transcripts and easily summarize videos with the most popular AI platforms.
// @author nucleargengar
// @match https://www.coursera.org/*
// @match https://chatgpt.com/*
// @match https://gemini.google.com/*
// @match https://chat.deepseek.com/*
// @match https://chat.qwenlm.ai/*
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @icon https://www.coursera.org/favicon.ico
// @license All Rights Reserved
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
// Global variable: auto-send feature
const autoSendKey = "autoSendEnabled";
let autoSendEnabled = GM_getValue(autoSendKey, false);
// Default prompt values
const defaultBriefPrompt = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize the content concisely while maintaining key points. Keep the readability high and, if necessary, use tables for clarity.";
const defaultInDepthPrompt = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize this content comprehensively and explain it in detail. Divide it into sections and keep its readability high. If necessary, support it with tables.";
// Function to return full language name using Intl.DisplayNames API
function getFullLanguageName() {
const rawLanguage = navigator.language || navigator.userLanguage;
const languageCode = rawLanguage.split('-')[0];
let fullLanguage;
try {
const displayNames = new Intl.DisplayNames(['en'], { type: 'language' });
fullLanguage = displayNames.of(languageCode);
} catch (error) {
fullLanguage = languageCode;
}
return fullLanguage;
}
// getPrefixText: Text to be sent to the AI platforms (the "Present it in" part will not be shown in the UI)
function getPrefixText() {
const summaryPreference = GM_getValue("summaryPreference", "in-depth");
const fullLanguageName = getFullLanguageName();
if (summaryPreference === "brief") {
return GM_getValue("briefPrompt", defaultBriefPrompt) + " Present it in " + fullLanguageName + " language.\n\n";
} else if (summaryPreference === "in-depth") {
return GM_getValue("inDepthPrompt", defaultInDepthPrompt) + " Present it in " + fullLanguageName + " language.\n\n";
} else if (summaryPreference === "customize") {
return GM_getValue("customPrompt", "") + "\n\n";
} else {
return GM_getValue("inDepthPrompt", defaultInDepthPrompt) + " Present it in " + fullLanguageName + " language.\n\n";
}
}
// Global queue: actions triggered with the ctrl key
let ctrlActionQueue = [];
// Wrapper to handle clicks with the ctrl key
function handleCtrlClick(event, action) {
if (event.ctrlKey) {
ctrlActionQueue.push(action);
console.log("Queued action for AI platform");
} else {
action();
}
}
// Executes queued actions when ctrl key is released
window.addEventListener('keyup', function(e) {
if (e.key === "Control") {
if (ctrlActionQueue.length > 0) {
ctrlActionQueue.forEach(fn => fn());
ctrlActionQueue = [];
}
}
});
// On Coursera pages (lecture pages): Set up UI and submission operations
if (window.location.hostname.includes("coursera.org")) {
GM_addStyle(`
/* Common UI styles for buttons */
#copyTranscriptButton, #chatGPTButton, #geminiButton, #deepseekButton, #qwenButton {
position: fixed;
background-color: #f5f5f5;
border: none;
color: #0056d2;
width: 40px;
height: 40px;
font-size: 18px;
cursor: pointer;
z-index: 9999;
border-radius: 50%;
transition: background-color 0.3s;
display: flex;
align-items: center;
justify-content: center;
}
#copyTranscriptButton:hover, #chatGPTButton:hover, #geminiButton:hover, #deepseekButton:hover, #qwenButton:hover {
background-color: #eee;
}
/* Initial left positioning; bottom will be set dynamically */
#copyTranscriptButton, #chatGPTButton, #geminiButton, #deepseekButton, #qwenButton {
left: 20px;
}
/* Message box style */
#messageBox {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 10000;
display: none;
}
`);
// Function to display messages
function displayMessage(message) {
const messageBox = document.getElementById('messageBox');
if (!messageBox) return;
messageBox.textContent = message;
messageBox.style.display = 'block';
setTimeout(() => messageBox.style.display = 'none', 3000);
}
// Fetch transcript and copy to clipboard
function fetchAndCopyTranscript(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
GM_setClipboard(response.responseText, "text");
console.log("Transcript copied to clipboard!");
displayMessage("Transcript copied to clipboard!");
} else {
console.error("Error fetching transcript:", response.status, response.statusText);
displayMessage("Error copying transcript: " + response.statusText);
}
},
onerror: error => {
console.error("Request error:", error);
displayMessage("Error copying transcript: " + error);
}
});
}
// Fetch transcript and send for ChatGPT
function fetchAndSendTranscriptForChatGPT(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
const prefixText = getPrefixText();
const combinedText = prefixText + response.responseText;
GM_setValue("chatgptTranscript", combinedText);
console.log("Transcript prepared for ChatGPT!");
displayMessage("Transcript prepared for ChatGPT!");
window.open("https://chatgpt.com", "_blank");
} else {
console.error("Error fetching transcript:", response.status, response.statusText);
displayMessage("Error sending transcript: " + response.statusText);
}
},
onerror: error => {
console.error("Request error:", error);
displayMessage("Error sending transcript: " + error);
}
});
}
// Fetch transcript and send for Gemini
function fetchAndSendTranscriptForGemini(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
const prefixText = getPrefixText();
const combinedText = prefixText + response.responseText;
GM_setValue("geminiTranscript", combinedText);
console.log("Transcript prepared for Gemini!");
displayMessage("Transcript prepared for Gemini!");
window.open("https://gemini.google.com", "_blank");
} else {
console.error("Error fetching transcript:", response.status, response.statusText);
displayMessage("Error sending transcript: " + response.statusText);
}
},
onerror: error => {
console.error("Request error:", error);
displayMessage("Error sending transcript: " + error);
}
});
}
// Fetch transcript and send for DeepSeek
function fetchAndSendTranscriptForDeepSeek(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
const prefixText = getPrefixText();
const combinedText = prefixText + response.responseText;
GM_setValue("deepseekTranscript", combinedText);
console.log("Transcript prepared for DeepSeek!");
displayMessage("Transcript prepared for DeepSeek!");
window.open("https://chat.deepseek.com", "_blank");
} else {
console.error("Error fetching transcript:", response.status, response.statusText);
displayMessage("Error sending transcript: " + response.statusText);
}
},
onerror: error => {
console.error("Request error:", error);
displayMessage("Error sending transcript: " + error);
}
});
}
// Fetch transcript and send for Qwen
function fetchAndSendTranscriptForQwen(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
const prefixText = getPrefixText();
const combinedText = prefixText + response.responseText;
GM_setValue("qwenTranscript", combinedText);
console.log("Transcript prepared for Qwen!");
displayMessage("Transcript prepared for Qwen!");
window.open("https://chat.qwenlm.ai", "_blank");
} else {
console.error("Error fetching transcript:", response.status, response.statusText);
displayMessage("Error sending transcript: " + response.statusText);
}
},
onerror: error => {
console.error("Request error:", error);
displayMessage("Error sending transcript: " + error);
}
});
}
// Get transcript link using XPath
function getTranscriptUrl() {
const xpath = "//li[@class='css-ap6dbz']/a[contains(@href, '/api/subtitleAssetProxy.v1/') and contains(@download, 'transcript.txt')]";
return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
// Copy transcript process
function copyTranscript() {
let transcriptLink = getTranscriptUrl();
if (transcriptLink) {
fetchAndCopyTranscript(transcriptLink.href);
} else {
displayMessage("Transcript link not found. Clicking Downloads tab.");
clickDownloadsTab();
const pollInterval = setInterval(() => {
transcriptLink = getTranscriptUrl();
if (transcriptLink) {
clearInterval(pollInterval);
fetchAndCopyTranscript(transcriptLink.href);
}
}, 500);
}
}
// Send transcript to ChatGPT
function sendTranscriptToChatGPT() {
let transcriptLink = getTranscriptUrl();
if (transcriptLink) {
fetchAndSendTranscriptForChatGPT(transcriptLink.href);
} else {
displayMessage("Transcript link not found. Clicking Downloads tab.");
clickDownloadsTab();
const pollInterval = setInterval(() => {
transcriptLink = getTranscriptUrl();
if (transcriptLink) {
clearInterval(pollInterval);
fetchAndSendTranscriptForChatGPT(transcriptLink.href);
}
}, 500);
}
}
// Send transcript to Gemini
function sendTranscriptToGemini() {
let transcriptLink = getTranscriptUrl();
if (transcriptLink) {
fetchAndSendTranscriptForGemini(transcriptLink.href);
} else {
displayMessage("Transcript link not found. Clicking Downloads tab.");
clickDownloadsTab();
const pollInterval = setInterval(() => {
transcriptLink = getTranscriptUrl();
if (transcriptLink) {
clearInterval(pollInterval);
fetchAndSendTranscriptForGemini(transcriptLink.href);
}
}, 500);
}
}
// Send transcript to DeepSeek
function sendTranscriptToDeepSeek() {
let transcriptLink = getTranscriptUrl();
if (transcriptLink) {
fetchAndSendTranscriptForDeepSeek(transcriptLink.href);
} else {
displayMessage("Transcript link not found. Clicking Downloads tab.");
clickDownloadsTab();
const pollInterval = setInterval(() => {
transcriptLink = getTranscriptUrl();
if (transcriptLink) {
clearInterval(pollInterval);
fetchAndSendTranscriptForDeepSeek(transcriptLink.href);
}
}, 500);
}
}
// Send transcript to Qwen
function sendTranscriptToQwen() {
let transcriptLink = getTranscriptUrl();
if (transcriptLink) {
fetchAndSendTranscriptForQwen(transcriptLink.href);
} else {
displayMessage("Transcript link not found. Clicking Downloads tab.");
clickDownloadsTab();
const pollInterval = setInterval(() => {
transcriptLink = getTranscriptUrl();
if (transcriptLink) {
clearInterval(pollInterval);
fetchAndSendTranscriptForQwen(transcriptLink.href);
}
}, 500);
}
}
// Add UI elements
function addUI() {
if (!document.getElementById('copyTranscriptButton')) {
const btnCopy = document.createElement('button');
btnCopy.id = 'copyTranscriptButton';
btnCopy.innerHTML = 'đź“‹';
btnCopy.title = 'Copy Transcript to Clipboard';
btnCopy.addEventListener('click', copyTranscript);
document.body.appendChild(btnCopy);
}
if (!document.getElementById('chatGPTButton')) {
const btnChatGPT = document.createElement('button');
btnChatGPT.id = 'chatGPTButton';
btnChatGPT.innerHTML = '';
btnChatGPT.title = 'Send Transcript to ChatGPT';
btnChatGPT.addEventListener('click', function(e) {
handleCtrlClick(e, sendTranscriptToChatGPT);
});
document.body.appendChild(btnChatGPT);
}
if (!document.getElementById('geminiButton')) {
const btnGemini = document.createElement('button');
btnGemini.id = 'geminiButton';
btnGemini.innerHTML = '
';
btnGemini.title = 'Send Transcript to Gemini';
btnGemini.addEventListener('click', function(e) {
handleCtrlClick(e, sendTranscriptToGemini);
});
document.body.appendChild(btnGemini);
}
if (!document.getElementById('qwenButton')) {
const btnQwen = document.createElement('button');
btnQwen.id = 'qwenButton';
btnQwen.innerHTML = '
';
btnQwen.title = 'Send Transcript to Qwen';
btnQwen.addEventListener('click', function(e) {
handleCtrlClick(e, sendTranscriptToQwen);
});
document.body.appendChild(btnQwen);
}
if (!document.getElementById('deepseekButton')) {
const btnDeepSeek = document.createElement('button');
btnDeepSeek.id = 'deepseekButton';
btnDeepSeek.innerHTML = '
';
btnDeepSeek.title = 'Send Transcript to DeepSeek';
btnDeepSeek.addEventListener('click', function(e) {
handleCtrlClick(e, sendTranscriptToDeepSeek);
});
document.body.appendChild(btnDeepSeek);
}
if (!document.getElementById('messageBox')) {
const messageBox = document.createElement('div');
messageBox.id = 'messageBox';
document.body.appendChild(messageBox);
}
}
// Remove UI elements
function removeUI() {
document.getElementById('copyTranscriptButton')?.remove();
document.getElementById('chatGPTButton')?.remove();
document.getElementById('geminiButton')?.remove();
document.getElementById('qwenButton')?.remove();
document.getElementById('deepseekButton')?.remove();
document.getElementById('messageBox')?.remove();
}
// Update icon visibility based on saved settings
function updateIconVisibility() {
const showCopy = GM_getValue("showCopyButton", true);
const showChatGPT = GM_getValue("showChatGPTButton", true);
const showGemini = GM_getValue("showGeminiButton", true);
const showDeepSeek = GM_getValue("showDeepSeekButton", true);
const showQwen = GM_getValue("showQwenButton", true);
const btnCopy = document.getElementById('copyTranscriptButton');
if (btnCopy) {
btnCopy.style.display = showCopy ? 'flex' : 'none';
}
const btnChatGPT = document.getElementById('chatGPTButton');
if (btnChatGPT) {
btnChatGPT.style.display = showChatGPT ? 'flex' : 'none';
}
const btnGemini = document.getElementById('geminiButton');
if (btnGemini) {
btnGemini.style.display = showGemini ? 'flex' : 'none';
}
const btnDeepSeek = document.getElementById('deepseekButton');
if (btnDeepSeek) {
btnDeepSeek.style.display = showDeepSeek ? 'flex' : 'none';
}
const btnQwen = document.getElementById('qwenButton');
if (btnQwen) {
btnQwen.style.display = showQwen ? 'flex' : 'none';
}
// Reposition visible icons
const iconOrder = [
'copyTranscriptButton',
'chatGPTButton',
'geminiButton',
'qwenButton',
'deepseekButton'
];
const spacing = 50; // space between icons
const baseBottom = 20; // starting bottom position
let visibleCount = 0;
iconOrder.forEach(id => {
const btn = document.getElementById(id);
if (btn && btn.style.display !== 'none') {
btn.style.bottom = (baseBottom + visibleCount * spacing) + 'px';
visibleCount++;
}
});
}
// Update UI
function updateUI() {
const isLecturePage = /^https:\/\/www\.coursera\.org\/learn\/[^\/]+\/lecture\/.+/.test(window.location.href);
if (isLecturePage) {
addUI();
updateIconVisibility();
clickDownloadsTab();
} else {
removeUI();
}
}
// Trigger updateUI when browser navigation changes
const originalPushState = history.pushState;
history.pushState = function(...args) {
const result = originalPushState.apply(this, args);
window.dispatchEvent(new Event('locationchange'));
return result;
};
const originalReplaceState = history.replaceState;
history.replaceState = function(...args) {
const result = originalReplaceState.apply(this, args);
window.dispatchEvent(new Event('locationchange'));
return result;
};
window.addEventListener('popstate', () => window.dispatchEvent(new Event('locationchange')));
window.addEventListener('locationchange', updateUI);
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', updateUI);
} else {
updateUI();
}
// Click Downloads tab
function clickDownloadsTab() {
let tab = document.querySelector("button[data-track-component='focused_lex_lecture_tabs_download']");
if (tab) {
tab.click();
console.log("Downloads tab clicked.");
} else {
console.log("Downloads tab not found, retrying.");
setTimeout(clickDownloadsTab, 1000);
}
}
window.addEventListener('load', clickDownloadsTab);
// Reload page when settings change
GM_addValueChangeListener("autoSendEnabled", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
GM_addValueChangeListener("showCopyButton", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
GM_addValueChangeListener("showChatGPTButton", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
GM_addValueChangeListener("showGeminiButton", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
GM_addValueChangeListener("showDeepSeekButton", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
GM_addValueChangeListener("showQwenButton", function(name, oldValue, newValue) {
if (oldValue !== newValue) {
location.reload();
}
});
}
// ChatGPT page: Automatically paste transcript
else if (window.location.hostname.includes("chatgpt.com")) {
function autoPasteTranscriptForChatGPT() {
const transcript = GM_getValue("chatgptTranscript", "");
if (!transcript) return;
console.log("Transcript found for ChatGPT, starting auto-paste.");
const intervalId = setInterval(() => {
const promptArea = document.getElementById("prompt-textarea");
if (promptArea) {
promptArea.textContent = transcript;
promptArea.dispatchEvent(new Event("input", { bubbles: true }));
promptArea.focus();
clearInterval(intervalId);
console.log("Transcript pasted in ChatGPT.");
GM_setValue("chatgptTranscript", "");
if (autoSendEnabled) {
const sendInterval = setInterval(() => {
const sendButton = document.querySelector('button[data-testid="send-button"]');
if (sendButton) {
sendButton.click();
console.log("Auto-send triggered for ChatGPT.");
clearInterval(sendInterval);
}
}, 500);
}
}
}, 500);
}
window.addEventListener("load", () => {
setTimeout(autoPasteTranscriptForChatGPT, 1000);
});
}
// Gemini page: Automatically paste transcript
else if (window.location.hostname.includes("gemini.google.com")) {
function autoPasteTranscriptForGemini() {
const transcript = GM_getValue("geminiTranscript", "");
if (!transcript) return;
console.log("Transcript found for Gemini, starting auto-paste.");
const intervalId = setInterval(() => {
const promptArea = document.querySelector("div.ql-editor.ql-blank.textarea.new-input-ui");
if (promptArea) {
promptArea.textContent = transcript;
promptArea.dispatchEvent(new Event("input", { bubbles: true }));
promptArea.focus();
clearInterval(intervalId);
console.log("Transcript pasted in Gemini.");
GM_setValue("geminiTranscript", "");
if (autoSendEnabled) {
const sendInterval = setInterval(() => {
const sendButton = document.querySelector('button[aria-label="Send message"]');
if (sendButton) {
sendButton.click();
console.log("Auto-send triggered for Gemini.");
clearInterval(sendInterval);
}
}, 500);
}
}
}, 500);
}
window.addEventListener("load", () => {
setTimeout(autoPasteTranscriptForGemini, 1000);
});
}
// DeepSeek page: Automatically paste transcript
else if (window.location.hostname.includes("chat.deepseek.com")) {
function autoPasteTranscriptForDeepSeek() {
const transcript = GM_getValue("deepseekTranscript", "");
if (!transcript) return;
console.log("Transcript found for DeepSeek, starting auto-paste.");
const intervalId = setInterval(() => {
const promptArea = document.getElementById("chat-input");
if (promptArea) {
promptArea.textContent = transcript;
promptArea.dispatchEvent(new Event("input", { bubbles: true }));
promptArea.focus();
clearInterval(intervalId);
console.log("Transcript pasted in DeepSeek.");
GM_setValue("deepseekTranscript", "");
if (autoSendEnabled) {
const sendInterval = setInterval(() => {
const sendButton = document.querySelector('div[role="button"].f6d670');
if (sendButton) {
sendButton.click();
console.log("Auto-send triggered for DeepSeek.");
clearInterval(sendInterval);
}
}, 500);
}
}
}, 500);
}
window.addEventListener("load", () => {
setTimeout(autoPasteTranscriptForDeepSeek, 1000);
});
}
// Qwen page: Automatically paste transcript
else if (window.location.hostname.includes("chat.qwenlm.ai")) {
function autoPasteTranscriptForQwen() {
const transcript = GM_getValue("qwenTranscript", "");
if (!transcript) return;
console.log("Transcript found for Qwen, starting auto-paste.");
const intervalId = setInterval(() => {
const promptArea = document.getElementById("chat-input");
if (promptArea) {
promptArea.value = transcript;
promptArea.dispatchEvent(new Event("input", { bubbles: true }));
promptArea.focus();
clearInterval(intervalId);
console.log("Transcript pasted in Qwen.");
GM_setValue("qwenTranscript", "");
if (autoSendEnabled) {
const sendInterval = setInterval(() => {
const sendButton = document.getElementById("send-message-button");
if (sendButton) {
sendButton.click();
console.log("Auto-send triggered for Qwen.");
clearInterval(sendInterval);
}
}, 500);
}
}
}, 500);
}
window.addEventListener("load", () => {
setTimeout(autoPasteTranscriptForQwen, 1000);
});
}
/* -----------------------------------------------------------------------
Settings Panel
-----------------------------------------------------------------------
This panel is opened via the "Settings" command.
The panel is organized as a rectangular window with two columns:
- Left column (Buttons): lists the current buttons.
- Right column (Summary Customizations): contains options for Brief, In‑Depth, and Customize.
For Brief and In‑Depth, a reset icon is placed immediately to the left of the toggle to restore the default prompt.
These prompts are sent to the AI platforms with a couple of newlines separating the prompt from the transcript.
The prompt entered in the Customize option is displayed on a separate line and edited in the same manner as the Brief/In‑Depth text.
The Customize prompt field uses the same modern, elegant scrollbar as the other fields.
- Below these, in the Functions section, there is an Auto-Send control.
- Clicking the Ă— button in the top right closes the settings panel without saving.
- Clicking the Save button saves the settings and reloads the page; the Save button changes color on hover.
*/
GM_addStyle(`
#videoSummarizerSettings {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #102a43;
color: #ffffff;
padding: 20px;
border-radius: 8px;
z-index: 100000;
width: 600px;
font-family: Arial, sans-serif;
box-shadow: 0 4px 10px rgba(0,0,0,0.5);
}
#videoSummarizerSettings h2 {
margin-top: 0;
text-align: center;
position: relative;
}
#settingsCloseButton {
position: absolute;
top: 5px;
right: 10px;
cursor: pointer;
font-size: 18px;
}
#videoSummarizerSettings h3 {
margin-bottom: 10px;
border-bottom: 1px solid #ffffff;
padding-bottom: 5px;
}
#videoSummarizerSettings .section {
margin-bottom: 15px;
}
.toggle-label {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
font-size: 14px;
}
.toggle-container {
display: flex;
align-items: center;
}
/* Toggle Switch Styles */
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 20px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #2196F3;
}
input:checked + .slider:before {
transform: translateX(20px);
}
/* Prompt preview/input styling with scrollbar */
.prompt-editable {
font-size: 12px;
color: #ccc;
margin-left: 10px;
padding: 5px;
background-color: #102a43;
border: 1px solid #ccc;
border-radius: 4px;
cursor: text;
max-height: 80px;
overflow-y: auto;
}
.prompt-editable::-webkit-scrollbar {
width: 8px;
cursor: default;
}
.prompt-editable::-webkit-scrollbar-track {
background: #102a43;
}
.prompt-editable::-webkit-scrollbar-thumb {
background: #2196F3;
border-radius: 4px;
}
/* Reset icon styling */
.reset-icon {
color: rgba(255,255,255,0.6);
font-size: 14px;
cursor: pointer;
margin-right: 5px;
}
.reset-icon:hover {
color: rgba(255,255,255,0.9);
}
/* Save button hover styling */
#settingsDoneButton {
width: 100%;
padding: 10px;
background-color: #2196F3;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
#settingsDoneButton:hover {
background-color: #1976D2;
}
`);
function addSettingsPanel() {
// Create the settings panel container (with close button)
const panel = document.createElement('div');
panel.id = 'videoSummarizerSettings';
panel.innerHTML = `