darkreader
Version:
Dark mode for every website
1,637 lines (1,613 loc) • 284 kB
JavaScript
/**
* Dark Reader v4.9.112
* https://darkreader.org/
*/
var MessageTypeUItoBG;
(function (MessageTypeUItoBG) {
MessageTypeUItoBG["GET_DATA"] = "ui-bg-get-data";
MessageTypeUItoBG["GET_DEVTOOLS_DATA"] = "ui-bg-get-devtools-data";
MessageTypeUItoBG["SUBSCRIBE_TO_CHANGES"] = "ui-bg-subscribe-to-changes";
MessageTypeUItoBG["UNSUBSCRIBE_FROM_CHANGES"] =
"ui-bg-unsubscribe-from-changes";
MessageTypeUItoBG["CHANGE_SETTINGS"] = "ui-bg-change-settings";
MessageTypeUItoBG["SET_THEME"] = "ui-bg-set-theme";
MessageTypeUItoBG["TOGGLE_ACTIVE_TAB"] = "ui-bg-toggle-active-tab";
MessageTypeUItoBG["MARK_NEWS_AS_READ"] = "ui-bg-mark-news-as-read";
MessageTypeUItoBG["MARK_NEWS_AS_DISPLAYED"] =
"ui-bg-mark-news-as-displayed";
MessageTypeUItoBG["LOAD_CONFIG"] = "ui-bg-load-config";
MessageTypeUItoBG["APPLY_DEV_DYNAMIC_THEME_FIXES"] =
"ui-bg-apply-dev-dynamic-theme-fixes";
MessageTypeUItoBG["RESET_DEV_DYNAMIC_THEME_FIXES"] =
"ui-bg-reset-dev-dynamic-theme-fixes";
MessageTypeUItoBG["APPLY_DEV_INVERSION_FIXES"] =
"ui-bg-apply-dev-inversion-fixes";
MessageTypeUItoBG["RESET_DEV_INVERSION_FIXES"] =
"ui-bg-reset-dev-inversion-fixes";
MessageTypeUItoBG["APPLY_DEV_STATIC_THEMES"] =
"ui-bg-apply-dev-static-themes";
MessageTypeUItoBG["RESET_DEV_STATIC_THEMES"] =
"ui-bg-reset-dev-static-themes";
MessageTypeUItoBG["START_ACTIVATION"] = "ui-bg-start-activation";
MessageTypeUItoBG["RESET_ACTIVATION"] = "ui-bg-reset-activation";
MessageTypeUItoBG["COLOR_SCHEME_CHANGE"] = "ui-bg-color-scheme-change";
MessageTypeUItoBG["HIDE_HIGHLIGHTS"] = "ui-bg-hide-highlights";
})(MessageTypeUItoBG || (MessageTypeUItoBG = {}));
var MessageTypeBGtoUI;
(function (MessageTypeBGtoUI) {
MessageTypeBGtoUI["CHANGES"] = "bg-ui-changes";
})(MessageTypeBGtoUI || (MessageTypeBGtoUI = {}));
var DebugMessageTypeBGtoUI;
(function (DebugMessageTypeBGtoUI) {
DebugMessageTypeBGtoUI["CSS_UPDATE"] = "debug-bg-ui-css-update";
DebugMessageTypeBGtoUI["UPDATE"] = "debug-bg-ui-update";
})(DebugMessageTypeBGtoUI || (DebugMessageTypeBGtoUI = {}));
var MessageTypeBGtoCS;
(function (MessageTypeBGtoCS) {
MessageTypeBGtoCS["ADD_CSS_FILTER"] = "bg-cs-add-css-filter";
MessageTypeBGtoCS["ADD_DYNAMIC_THEME"] = "bg-cs-add-dynamic-theme";
MessageTypeBGtoCS["ADD_STATIC_THEME"] = "bg-cs-add-static-theme";
MessageTypeBGtoCS["ADD_SVG_FILTER"] = "bg-cs-add-svg-filter";
MessageTypeBGtoCS["CLEAN_UP"] = "bg-cs-clean-up";
MessageTypeBGtoCS["FETCH_RESPONSE"] = "bg-cs-fetch-response";
MessageTypeBGtoCS["UNSUPPORTED_SENDER"] = "bg-cs-unsupported-sender";
})(MessageTypeBGtoCS || (MessageTypeBGtoCS = {}));
var DebugMessageTypeBGtoCS;
(function (DebugMessageTypeBGtoCS) {
DebugMessageTypeBGtoCS["RELOAD"] = "debug-bg-cs-reload";
})(DebugMessageTypeBGtoCS || (DebugMessageTypeBGtoCS = {}));
var MessageTypeCStoBG;
(function (MessageTypeCStoBG) {
MessageTypeCStoBG["COLOR_SCHEME_CHANGE"] = "cs-bg-color-scheme-change";
MessageTypeCStoBG["DARK_THEME_DETECTED"] = "cs-bg-dark-theme-detected";
MessageTypeCStoBG["DARK_THEME_NOT_DETECTED"] =
"cs-bg-dark-theme-not-detected";
MessageTypeCStoBG["FETCH"] = "cs-bg-fetch";
MessageTypeCStoBG["DOCUMENT_CONNECT"] = "cs-bg-document-connect";
MessageTypeCStoBG["DOCUMENT_FORGET"] = "cs-bg-document-forget";
MessageTypeCStoBG["DOCUMENT_FREEZE"] = "cs-bg-document-freeze";
MessageTypeCStoBG["DOCUMENT_RESUME"] = "cs-bg-document-resume";
})(MessageTypeCStoBG || (MessageTypeCStoBG = {}));
var DebugMessageTypeCStoBG;
(function (DebugMessageTypeCStoBG) {
DebugMessageTypeCStoBG["LOG"] = "debug-cs-bg-log";
})(DebugMessageTypeCStoBG || (DebugMessageTypeCStoBG = {}));
var MessageTypeCStoUI;
(function (MessageTypeCStoUI) {
MessageTypeCStoUI["EXPORT_CSS_RESPONSE"] = "cs-ui-export-css-response";
})(MessageTypeCStoUI || (MessageTypeCStoUI = {}));
var MessageTypeUItoCS;
(function (MessageTypeUItoCS) {
MessageTypeUItoCS["EXPORT_CSS"] = "ui-cs-export-css";
})(MessageTypeUItoCS || (MessageTypeUItoCS = {}));
const isNavigatorDefined = typeof navigator !== "undefined";
const userAgent = isNavigatorDefined
? navigator.userAgentData && Array.isArray(navigator.userAgentData.brands)
? navigator.userAgentData.brands
.map((brand) => `${brand.brand.toLowerCase()} ${brand.version}`)
.join(" ")
: navigator.userAgent.toLowerCase()
: "some useragent";
const platform = isNavigatorDefined
? navigator.userAgentData &&
typeof navigator.userAgentData.platform === "string"
? navigator.userAgentData.platform.toLowerCase()
: navigator.platform.toLowerCase()
: "some platform";
const isChromium =
userAgent.includes("chrome") || userAgent.includes("chromium");
const isFirefox =
userAgent.includes("firefox") ||
userAgent.includes("thunderbird") ||
userAgent.includes("librewolf");
const isSafari = userAgent.includes("safari") && !isChromium;
const isWindows = platform.startsWith("win");
const isMacOS = platform.startsWith("mac");
isNavigatorDefined && navigator.userAgentData
? navigator.userAgentData.mobile
: userAgent.includes("mobile");
const isShadowDomSupported = typeof ShadowRoot === "function";
const isMatchMediaChangeEventListenerSupported =
typeof MediaQueryList === "function" &&
typeof MediaQueryList.prototype.addEventListener === "function";
const isLayerRuleSupported = typeof CSSLayerBlockRule === "function";
(() => {
const m = userAgent.match(/chrom(?:e|ium)(?:\/| )([^ ]+)/);
if (m && m[1]) {
return m[1];
}
return "";
})();
(() => {
const m = userAgent.match(/(?:firefox|librewolf)(?:\/| )([^ ]+)/);
if (m && m[1]) {
return m[1];
}
return "";
})();
const isDefinedSelectorSupported = (() => {
try {
document.querySelector(":defined");
return true;
} catch (err) {
return false;
}
})();
const isCSSColorSchemePropSupported = (() => {
try {
if (typeof document === "undefined") {
return false;
}
const el = document.createElement("div");
if (!el || typeof el.style !== "object") {
return false;
}
if (typeof el.style.colorScheme === "string") {
return true;
}
el.setAttribute("style", "color-scheme: dark");
return el.style.colorScheme === "dark";
} catch (e) {
return false;
}
})();
async function getOKResponse(url, mimeType, origin) {
const credentials =
origin && url.startsWith(`${origin}/`) ? undefined : "omit";
const response = await fetch(url, {
cache: "force-cache",
credentials,
referrer: origin
});
if (
isFirefox &&
mimeType === "text/css" &&
url.startsWith("moz-extension://") &&
url.endsWith(".css")
) {
return response;
}
if (
mimeType &&
!response.headers.get("Content-Type").startsWith(mimeType)
) {
throw new Error(`Mime type mismatch when loading ${url}`);
}
if (!response.ok) {
throw new Error(
`Unable to load ${url} ${response.status} ${response.statusText}`
);
}
return response;
}
async function loadAsDataURL(url, mimeType) {
const response = await getOKResponse(url, mimeType);
return await readResponseAsDataURL(response);
}
async function loadAsBlob(url, mimeType) {
const response = await getOKResponse(url, mimeType);
return await response.blob();
}
async function readResponseAsDataURL(response) {
const blob = await response.blob();
const dataURL = await new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
return dataURL;
}
async function loadAsText(url, mimeType, origin) {
const response = await getOKResponse(url, mimeType, origin);
return await response.text();
}
const throwCORSError = async (url) => {
return Promise.reject(
new Error(
[
"Embedded Dark Reader cannot access a cross-origin resource",
url,
"Overview your URLs and CORS policies or use",
"`DarkReader.setFetchMethod(fetch: (url) => Promise<Response>))`.",
"See if using `DarkReader.setFetchMethod(window.fetch)`",
"before `DarkReader.enable()` works."
].join(" ")
)
);
};
let fetcher = throwCORSError;
function setFetchMethod$1(fetch) {
if (fetch) {
fetcher = fetch;
} else {
fetcher = throwCORSError;
}
}
async function callFetchMethod(url) {
return await fetcher(url);
}
if (!window.chrome) {
window.chrome = {};
}
if (!chrome.runtime) {
chrome.runtime = {};
}
const messageListeners = new Set();
async function sendMessage(...args) {
if (args[0] && args[0].type === MessageTypeCStoBG.FETCH) {
const {id} = args[0];
try {
const {url, responseType} = args[0].data;
const response = await callFetchMethod(url);
let text;
if (responseType === "data-url") {
text = await readResponseAsDataURL(response);
} else {
text = await response.text();
}
messageListeners.forEach((cb) =>
cb({
type: MessageTypeBGtoCS.FETCH_RESPONSE,
data: text,
error: null,
id
})
);
} catch (error) {
console.error(error);
messageListeners.forEach((cb) =>
cb({
type: MessageTypeBGtoCS.FETCH_RESPONSE,
data: null,
error,
id
})
);
}
}
}
function addMessageListener(callback) {
messageListeners.add(callback);
}
if (typeof chrome.runtime.sendMessage === "function") {
const nativeSendMessage = chrome.runtime.sendMessage;
chrome.runtime.sendMessage = (...args) => {
sendMessage(...args);
nativeSendMessage.apply(chrome.runtime, args);
};
} else {
chrome.runtime.sendMessage = sendMessage;
}
if (!chrome.runtime.onMessage) {
chrome.runtime.onMessage = {};
}
if (typeof chrome.runtime.onMessage.addListener === "function") {
const nativeAddListener = chrome.runtime.onMessage.addListener;
chrome.runtime.onMessage.addListener = (...args) => {
addMessageListener(args[0]);
nativeAddListener.apply(chrome.runtime.onMessage, args);
};
} else {
chrome.runtime.onMessage.addListener = (...args) =>
addMessageListener(args[0]);
}
var ThemeEngine;
(function (ThemeEngine) {
ThemeEngine["cssFilter"] = "cssFilter";
ThemeEngine["svgFilter"] = "svgFilter";
ThemeEngine["staticTheme"] = "staticTheme";
ThemeEngine["dynamicTheme"] = "dynamicTheme";
})(ThemeEngine || (ThemeEngine = {}));
var AutomationMode;
(function (AutomationMode) {
AutomationMode["NONE"] = "";
AutomationMode["TIME"] = "time";
AutomationMode["SYSTEM"] = "system";
AutomationMode["LOCATION"] = "location";
})(AutomationMode || (AutomationMode = {}));
const DEFAULT_COLORS = {
darkScheme: {
background: "#181a1b",
text: "#e8e6e3"
},
lightScheme: {
background: "#dcdad7",
text: "#181a1b"
}
};
const DEFAULT_THEME = {
mode: 1,
brightness: 100,
contrast: 100,
grayscale: 0,
sepia: 0,
useFont: false,
fontFamily: isMacOS
? "Helvetica Neue"
: isWindows
? "Segoe UI"
: "Open Sans",
textStroke: 0,
engine: ThemeEngine.dynamicTheme,
stylesheet: "",
darkSchemeBackgroundColor: DEFAULT_COLORS.darkScheme.background,
darkSchemeTextColor: DEFAULT_COLORS.darkScheme.text,
lightSchemeBackgroundColor: DEFAULT_COLORS.lightScheme.background,
lightSchemeTextColor: DEFAULT_COLORS.lightScheme.text,
scrollbarColor: "",
selectionColor: "auto",
styleSystemControls: !isCSSColorSchemePropSupported,
lightColorScheme: "Default",
darkColorScheme: "Default",
immediateModify: false
};
const filterModeSites = [
"*.officeapps.live.com",
"*.sharepoint.com",
"docs.google.com",
"onedrive.live.com"
];
({
customThemes: filterModeSites.map((url) => {
const engine = ThemeEngine.cssFilter;
return {
url: [url],
theme: {...DEFAULT_THEME, engine},
builtIn: true
};
}),
automation: {
mode: AutomationMode.NONE
}
});
function getMatches(regex, input, group = 0) {
const matches = [];
let m;
while ((m = regex.exec(input))) {
matches.push(m[group]);
}
return matches;
}
function getMatchesWithOffsets(regex, input, group = 0) {
const matches = [];
let m;
while ((m = regex.exec(input))) {
matches.push({text: m[group], offset: m.index});
}
return matches;
}
function getHashCode(text) {
const len = text.length;
let hash = 0;
for (let i = 0; i < len; i++) {
const c = text.charCodeAt(i);
hash = ((hash << 5) - hash + c) & 4294967295;
}
return hash;
}
function escapeRegExpSpecialChars(input) {
return input.replaceAll(/[\^$.*+?\(\)\[\]{}|\-\\]/g, "\\$&");
}
function getParenthesesRange(input, searchStartIndex = 0) {
return getOpenCloseRange(input, searchStartIndex, "(", ")", []);
}
function getOpenCloseRange(
input,
searchStartIndex,
openToken,
closeToken,
excludeRanges
) {
let indexOf;
if (excludeRanges.length === 0) {
indexOf = (token, pos) => input.indexOf(token, pos);
} else {
indexOf = (token, pos) =>
indexOfExcluding(input, token, pos, excludeRanges);
}
const {length} = input;
let depth = 0;
let firstOpenIndex = -1;
for (let i = searchStartIndex; i < length; i++) {
if (depth === 0) {
const openIndex = indexOf(openToken, i);
if (openIndex < 0) {
break;
}
firstOpenIndex = openIndex;
depth++;
i = openIndex;
} else {
const closeIndex = indexOf(closeToken, i);
if (closeIndex < 0) {
break;
}
const openIndex = indexOf(openToken, i);
if (openIndex < 0 || closeIndex <= openIndex) {
depth--;
if (depth === 0) {
return {start: firstOpenIndex, end: closeIndex + 1};
}
i = closeIndex;
} else {
depth++;
i = openIndex;
}
}
}
return null;
}
function indexOfExcluding(input, search, position, excludeRanges) {
const i = input.indexOf(search, position);
const exclusion = excludeRanges.find((r) => i >= r.start && i < r.end);
if (exclusion) {
return indexOfExcluding(input, search, exclusion.end, excludeRanges);
}
return i;
}
function splitExcluding(input, separator, excludeRanges) {
const parts = [];
let commaIndex = -1;
let currIndex = 0;
while (
(commaIndex = indexOfExcluding(
input,
separator,
currIndex,
excludeRanges
)) >= 0
) {
parts.push(input.substring(currIndex, commaIndex).trim());
currIndex = commaIndex + 1;
}
parts.push(input.substring(currIndex).trim());
return parts;
}
let anchor;
const parsedURLCache = new Map();
function fixBaseURL($url) {
if (!anchor) {
anchor = document.createElement("a");
}
anchor.href = $url;
return anchor.href;
}
function parseURL($url, $base = null) {
const key = `${$url}${$base ? `;${$base}` : ""}`;
if (parsedURLCache.has(key)) {
return parsedURLCache.get(key);
}
if ($base) {
const parsedURL = new URL($url, fixBaseURL($base));
parsedURLCache.set(key, parsedURL);
return parsedURL;
}
const parsedURL = new URL(fixBaseURL($url));
parsedURLCache.set($url, parsedURL);
return parsedURL;
}
function getAbsoluteURL($base, $relative) {
if ($relative.match(/^data\\?\:/)) {
return $relative;
}
if (/^\/\//.test($relative)) {
return `${location.protocol}${$relative}`;
}
const b = parseURL($base);
const a = parseURL($relative, b.href);
return a.href;
}
function isRelativeHrefOnAbsolutePath(href) {
if (href.startsWith("data:")) {
return true;
}
const url = parseURL(href);
if (url.protocol !== location.protocol) {
return false;
}
if (url.hostname !== location.hostname) {
return false;
}
if (url.port !== location.port) {
return false;
}
return url.pathname === location.pathname;
}
const excludedSelectors = [
"pre",
"pre *",
"code",
'[aria-hidden="true"]',
'[class*="fa-"]',
".fa",
".fab",
".fad",
".fal",
".far",
".fas",
".fass",
".fasr",
".fat",
".icofont",
'[style*="font-"]',
'[class*="icon"]',
'[class*="Icon"]',
'[class*="symbol"]',
'[class*="Symbol"]',
".glyphicon",
'[class*="material-symbol"]',
'[class*="material-icon"]',
"mu",
'[class*="mu-"]',
".typcn",
'[class*="vjs-"]'
];
function createTextStyle(config) {
const lines = [];
lines.push(`*:not(${excludedSelectors.join(", ")}) {`);
if (config.useFont && config.fontFamily) {
lines.push(` font-family: ${config.fontFamily} !important;`);
}
if (config.textStroke > 0) {
lines.push(` -webkit-text-stroke: ${config.textStroke}px !important;`);
lines.push(` text-stroke: ${config.textStroke}px !important;`);
}
lines.push("}");
return lines.join("\n");
}
function isArrayLike(items) {
return items.length != null;
}
function forEach(items, iterator) {
if (isArrayLike(items)) {
for (let i = 0, len = items.length; i < len; i++) {
iterator(items[i]);
}
} else {
for (const item of items) {
iterator(item);
}
}
}
function push(array, addition) {
forEach(addition, (a) => array.push(a));
}
function toArray(items) {
const results = [];
for (let i = 0, len = items.length; i < len; i++) {
results.push(items[i]);
}
return results;
}
function scale(x, inLow, inHigh, outLow, outHigh) {
return ((x - inLow) * (outHigh - outLow)) / (inHigh - inLow) + outLow;
}
function clamp(x, min, max) {
return Math.min(max, Math.max(min, x));
}
function multiplyMatrices(m1, m2) {
const result = [];
for (let i = 0, len = m1.length; i < len; i++) {
result[i] = [];
for (let j = 0, len2 = m2[0].length; j < len2; j++) {
let sum = 0;
for (let k = 0, len3 = m1[0].length; k < len3; k++) {
sum += m1[i][k] * m2[k][j];
}
result[i][j] = sum;
}
}
return result;
}
function createFilterMatrix(config) {
let m = Matrix.identity();
if (config.sepia !== 0) {
m = multiplyMatrices(m, Matrix.sepia(config.sepia / 100));
}
if (config.grayscale !== 0) {
m = multiplyMatrices(m, Matrix.grayscale(config.grayscale / 100));
}
if (config.contrast !== 100) {
m = multiplyMatrices(m, Matrix.contrast(config.contrast / 100));
}
if (config.brightness !== 100) {
m = multiplyMatrices(m, Matrix.brightness(config.brightness / 100));
}
if (config.mode === 1) {
m = multiplyMatrices(m, Matrix.invertNHue());
}
return m;
}
function applyColorMatrix([r, g, b], matrix) {
const rgb = [[r / 255], [g / 255], [b / 255], [1], [1]];
const result = multiplyMatrices(matrix, rgb);
return [0, 1, 2].map((i) => clamp(Math.round(result[i][0] * 255), 0, 255));
}
const Matrix = {
identity() {
return [
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
},
invertNHue() {
return [
[0.333, -0.667, -0.667, 0, 1],
[-0.667, 0.333, -0.667, 0, 1],
[-0.667, -0.667, 0.333, 0, 1],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
},
brightness(v) {
return [
[v, 0, 0, 0, 0],
[0, v, 0, 0, 0],
[0, 0, v, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
},
contrast(v) {
const t = (1 - v) / 2;
return [
[v, 0, 0, 0, t],
[0, v, 0, 0, t],
[0, 0, v, 0, t],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
},
sepia(v) {
return [
[
0.393 + 0.607 * (1 - v),
0.769 - 0.769 * (1 - v),
0.189 - 0.189 * (1 - v),
0,
0
],
[
0.349 - 0.349 * (1 - v),
0.686 + 0.314 * (1 - v),
0.168 - 0.168 * (1 - v),
0,
0
],
[
0.272 - 0.272 * (1 - v),
0.534 - 0.534 * (1 - v),
0.131 + 0.869 * (1 - v),
0,
0
],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
},
grayscale(v) {
return [
[
0.2126 + 0.7874 * (1 - v),
0.7152 - 0.7152 * (1 - v),
0.0722 - 0.0722 * (1 - v),
0,
0
],
[
0.2126 - 0.2126 * (1 - v),
0.7152 + 0.2848 * (1 - v),
0.0722 - 0.0722 * (1 - v),
0,
0
],
[
0.2126 - 0.2126 * (1 - v),
0.7152 - 0.7152 * (1 - v),
0.0722 + 0.9278 * (1 - v),
0,
0
],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]
];
}
};
var FilterMode;
(function (FilterMode) {
FilterMode[(FilterMode["light"] = 0)] = "light";
FilterMode[(FilterMode["dark"] = 1)] = "dark";
})(FilterMode || (FilterMode = {}));
function getCSSFilterValue(config) {
const filters = [];
if (config.mode === FilterMode.dark) {
filters.push("invert(100%) hue-rotate(180deg)");
}
if (config.brightness !== 100) {
filters.push(`brightness(${config.brightness}%)`);
}
if (config.contrast !== 100) {
filters.push(`contrast(${config.contrast}%)`);
}
if (config.grayscale !== 0) {
filters.push(`grayscale(${config.grayscale}%)`);
}
if (config.sepia !== 0) {
filters.push(`sepia(${config.sepia}%)`);
}
if (filters.length === 0) {
return null;
}
return filters.join(" ");
}
function evalMath(expression) {
const rpnStack = [];
const workingStack = [];
let lastToken;
for (let i = 0, len = expression.length; i < len; i++) {
const token = expression[i];
if (!token || token === " ") {
continue;
}
if (operators.has(token)) {
const op = operators.get(token);
while (workingStack.length) {
const currentOp = operators.get(workingStack[0]);
if (!currentOp) {
break;
}
if (op.lessOrEqualThan(currentOp)) {
rpnStack.push(workingStack.shift());
} else {
break;
}
}
workingStack.unshift(token);
} else if (!lastToken || operators.has(lastToken)) {
rpnStack.push(token);
} else {
rpnStack[rpnStack.length - 1] += token;
}
lastToken = token;
}
rpnStack.push(...workingStack);
const stack = [];
for (let i = 0, len = rpnStack.length; i < len; i++) {
const op = operators.get(rpnStack[i]);
if (op) {
const args = stack.splice(0, 2);
stack.push(op.exec(args[1], args[0]));
} else {
stack.unshift(parseFloat(rpnStack[i]));
}
}
return stack[0];
}
class Operator {
constructor(precedence, method) {
this.precendce = precedence;
this.execMethod = method;
}
exec(left, right) {
return this.execMethod(left, right);
}
lessOrEqualThan(op) {
return this.precendce <= op.precendce;
}
}
const operators = new Map([
["+", new Operator(1, (left, right) => left + right)],
["-", new Operator(1, (left, right) => left - right)],
["*", new Operator(2, (left, right) => left * right)],
["/", new Operator(2, (left, right) => left / right)]
]);
const isSystemDarkModeEnabled = () =>
matchMedia("(prefers-color-scheme: dark)").matches;
const hslaParseCache = new Map();
const rgbaParseCache = new Map();
function parseColorWithCache($color) {
$color = $color.trim();
if (rgbaParseCache.has($color)) {
return rgbaParseCache.get($color);
}
if ($color.includes("calc(")) {
$color = lowerCalcExpression($color);
}
const color = parse($color);
if (color) {
rgbaParseCache.set($color, color);
return color;
}
return null;
}
function parseToHSLWithCache(color) {
if (hslaParseCache.has(color)) {
return hslaParseCache.get(color);
}
const rgb = parseColorWithCache(color);
if (!rgb) {
return null;
}
const hsl = rgbToHSL(rgb);
hslaParseCache.set(color, hsl);
return hsl;
}
function clearColorCache() {
hslaParseCache.clear();
rgbaParseCache.clear();
}
function hslToRGB({h, s, l, a = 1}) {
if (s === 0) {
const [r, b, g] = [l, l, l].map((x) => Math.round(x * 255));
return {r, g, b, a};
}
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
const m = l - c / 2;
const [r, g, b] = (
h < 60
? [c, x, 0]
: h < 120
? [x, c, 0]
: h < 180
? [0, c, x]
: h < 240
? [0, x, c]
: h < 300
? [x, 0, c]
: [c, 0, x]
).map((n) => Math.round((n + m) * 255));
return {r, g, b, a};
}
function rgbToHSL({r: r255, g: g255, b: b255, a = 1}) {
const r = r255 / 255;
const g = g255 / 255;
const b = b255 / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const c = max - min;
const l = (max + min) / 2;
if (c === 0) {
return {h: 0, s: 0, l, a};
}
let h =
(max === r
? ((g - b) / c) % 6
: max === g
? (b - r) / c + 2
: (r - g) / c + 4) * 60;
if (h < 0) {
h += 360;
}
const s = c / (1 - Math.abs(2 * l - 1));
return {h, s, l, a};
}
function toFixed(n, digits = 0) {
const fixed = n.toFixed(digits);
if (digits === 0) {
return fixed;
}
const dot = fixed.indexOf(".");
if (dot >= 0) {
const zerosMatch = fixed.match(/0+$/);
if (zerosMatch) {
if (zerosMatch.index === dot + 1) {
return fixed.substring(0, dot);
}
return fixed.substring(0, zerosMatch.index);
}
}
return fixed;
}
function rgbToString(rgb) {
const {r, g, b, a} = rgb;
if (a != null && a < 1) {
return `rgba(${toFixed(r)}, ${toFixed(g)}, ${toFixed(b)}, ${toFixed(a, 2)})`;
}
return `rgb(${toFixed(r)}, ${toFixed(g)}, ${toFixed(b)})`;
}
function rgbToHexString({r, g, b, a}) {
return `#${(a != null && a < 1 ? [r, g, b, Math.round(a * 255)] : [r, g, b])
.map((x) => {
return `${x < 16 ? "0" : ""}${x.toString(16)}`;
})
.join("")}`;
}
function hslToString(hsl) {
const {h, s, l, a} = hsl;
if (a != null && a < 1) {
return `hsla(${toFixed(h)}, ${toFixed(s * 100)}%, ${toFixed(l * 100)}%, ${toFixed(a, 2)})`;
}
return `hsl(${toFixed(h)}, ${toFixed(s * 100)}%, ${toFixed(l * 100)}%)`;
}
const rgbMatch = /^rgba?\([^\(\)]+\)$/;
const hslMatch = /^hsla?\([^\(\)]+\)$/;
const hexMatch = /^#[0-9a-f]+$/i;
const supportedColorFuncs = [
"color",
"color-mix",
"hwb",
"lab",
"lch",
"oklab",
"oklch"
];
function parse($color) {
const c = $color.trim().toLowerCase();
if (c.includes("(from ")) {
if (c.indexOf("(from") !== c.lastIndexOf("(from")) {
return null;
}
return domParseColor(c);
}
if (c.match(rgbMatch)) {
if (c.startsWith("rgb(#") || c.startsWith("rgba(#")) {
if (c.lastIndexOf("rgb") > 0) {
return null;
}
return domParseColor(c);
}
return parseRGB(c);
}
if (c.match(hslMatch)) {
return parseHSL(c);
}
if (c.match(hexMatch)) {
return parseHex(c);
}
if (knownColors.has(c)) {
return getColorByName(c);
}
if (systemColors.has(c)) {
return getSystemColor(c);
}
if (c === "transparent") {
return {r: 0, g: 0, b: 0, a: 0};
}
if (
c.endsWith(")") &&
supportedColorFuncs.some(
(fn) =>
c.startsWith(fn) &&
c[fn.length] === "(" &&
c.lastIndexOf(fn) === 0
)
) {
return domParseColor(c);
}
if (c.startsWith("light-dark(") && c.endsWith(")")) {
const match = c.match(
/^light-dark\(\s*([a-z]+(\(.*\))?),\s*([a-z]+(\(.*\))?)\s*\)$/
);
if (match) {
const schemeColor = isSystemDarkModeEnabled() ? match[3] : match[1];
return parse(schemeColor);
}
}
return null;
}
function getNumbers($color) {
const numbers = [];
let prevPos = 0;
let isMining = false;
const startIndex = $color.indexOf("(");
$color = $color.substring(startIndex + 1, $color.length - 1);
for (let i = 0; i < $color.length; i++) {
const c = $color[i];
if ((c >= "0" && c <= "9") || c === "." || c === "+" || c === "-") {
isMining = true;
} else if (isMining && (c === " " || c === "," || c === "/")) {
numbers.push($color.substring(prevPos, i));
isMining = false;
prevPos = i + 1;
} else if (!isMining) {
prevPos = i + 1;
}
}
if (isMining) {
numbers.push($color.substring(prevPos, $color.length));
}
return numbers;
}
function getNumbersFromString(str, range, units) {
const raw = getNumbers(str);
const unitsList = Object.entries(units);
const numbers = raw
.map((r) => r.trim())
.map((r, i) => {
let n;
const unit = unitsList.find(([u]) => r.endsWith(u));
if (unit) {
n =
(parseFloat(r.substring(0, r.length - unit[0].length)) /
unit[1]) *
range[i];
} else {
n = parseFloat(r);
}
if (range[i] > 1) {
return Math.round(n);
}
return n;
});
return numbers;
}
const rgbRange = [255, 255, 255, 1];
const rgbUnits = {"%": 100};
function parseRGB($rgb) {
const [r, g, b, a = 1] = getNumbersFromString($rgb, rgbRange, rgbUnits);
if (r == null || g == null || b == null || a == null) {
return null;
}
return {r, g, b, a};
}
const hslRange = [360, 1, 1, 1];
const hslUnits = {"%": 100, "deg": 360, "rad": 2 * Math.PI, "turn": 1};
function parseHSL($hsl) {
const [h, s, l, a = 1] = getNumbersFromString($hsl, hslRange, hslUnits);
if (h == null || s == null || l == null || a == null) {
return null;
}
return hslToRGB({h, s, l, a});
}
function parseHex($hex) {
const h = $hex.substring(1);
switch (h.length) {
case 3:
case 4: {
const [r, g, b] = [0, 1, 2].map((i) =>
parseInt(`${h[i]}${h[i]}`, 16)
);
const a = h.length === 3 ? 1 : parseInt(`${h[3]}${h[3]}`, 16) / 255;
return {r, g, b, a};
}
case 6:
case 8: {
const [r, g, b] = [0, 2, 4].map((i) =>
parseInt(h.substring(i, i + 2), 16)
);
const a =
h.length === 6 ? 1 : parseInt(h.substring(6, 8), 16) / 255;
return {r, g, b, a};
}
}
return null;
}
function getColorByName($color) {
const n = knownColors.get($color);
return {
r: (n >> 16) & 255,
g: (n >> 8) & 255,
b: (n >> 0) & 255,
a: 1
};
}
function getSystemColor($color) {
const n = systemColors.get($color);
return {
r: (n >> 16) & 255,
g: (n >> 8) & 255,
b: (n >> 0) & 255,
a: 1
};
}
function lowerCalcExpression(color) {
let searchIndex = 0;
const replaceBetweenIndices = (start, end, replacement) => {
color = color.substring(0, start) + replacement + color.substring(end);
};
while ((searchIndex = color.indexOf("calc(")) !== -1) {
const range = getParenthesesRange(color, searchIndex);
if (!range) {
break;
}
let slice = color.slice(range.start + 1, range.end - 1);
const includesPercentage = slice.includes("%");
slice = slice.split("%").join("");
const output = Math.round(evalMath(slice));
replaceBetweenIndices(
range.start - 4,
range.end,
output + (includesPercentage ? "%" : "")
);
}
return color;
}
const knownColors = new Map(
Object.entries({
aliceblue: 0xf0f8ff,
antiquewhite: 0xfaebd7,
aqua: 0x00ffff,
aquamarine: 0x7fffd4,
azure: 0xf0ffff,
beige: 0xf5f5dc,
bisque: 0xffe4c4,
black: 0x000000,
blanchedalmond: 0xffebcd,
blue: 0x0000ff,
blueviolet: 0x8a2be2,
brown: 0xa52a2a,
burlywood: 0xdeb887,
cadetblue: 0x5f9ea0,
chartreuse: 0x7fff00,
chocolate: 0xd2691e,
coral: 0xff7f50,
cornflowerblue: 0x6495ed,
cornsilk: 0xfff8dc,
crimson: 0xdc143c,
cyan: 0x00ffff,
darkblue: 0x00008b,
darkcyan: 0x008b8b,
darkgoldenrod: 0xb8860b,
darkgray: 0xa9a9a9,
darkgrey: 0xa9a9a9,
darkgreen: 0x006400,
darkkhaki: 0xbdb76b,
darkmagenta: 0x8b008b,
darkolivegreen: 0x556b2f,
darkorange: 0xff8c00,
darkorchid: 0x9932cc,
darkred: 0x8b0000,
darksalmon: 0xe9967a,
darkseagreen: 0x8fbc8f,
darkslateblue: 0x483d8b,
darkslategray: 0x2f4f4f,
darkslategrey: 0x2f4f4f,
darkturquoise: 0x00ced1,
darkviolet: 0x9400d3,
deeppink: 0xff1493,
deepskyblue: 0x00bfff,
dimgray: 0x696969,
dimgrey: 0x696969,
dodgerblue: 0x1e90ff,
firebrick: 0xb22222,
floralwhite: 0xfffaf0,
forestgreen: 0x228b22,
fuchsia: 0xff00ff,
gainsboro: 0xdcdcdc,
ghostwhite: 0xf8f8ff,
gold: 0xffd700,
goldenrod: 0xdaa520,
gray: 0x808080,
grey: 0x808080,
green: 0x008000,
greenyellow: 0xadff2f,
honeydew: 0xf0fff0,
hotpink: 0xff69b4,
indianred: 0xcd5c5c,
indigo: 0x4b0082,
ivory: 0xfffff0,
khaki: 0xf0e68c,
lavender: 0xe6e6fa,
lavenderblush: 0xfff0f5,
lawngreen: 0x7cfc00,
lemonchiffon: 0xfffacd,
lightblue: 0xadd8e6,
lightcoral: 0xf08080,
lightcyan: 0xe0ffff,
lightgoldenrodyellow: 0xfafad2,
lightgray: 0xd3d3d3,
lightgrey: 0xd3d3d3,
lightgreen: 0x90ee90,
lightpink: 0xffb6c1,
lightsalmon: 0xffa07a,
lightseagreen: 0x20b2aa,
lightskyblue: 0x87cefa,
lightslategray: 0x778899,
lightslategrey: 0x778899,
lightsteelblue: 0xb0c4de,
lightyellow: 0xffffe0,
lime: 0x00ff00,
limegreen: 0x32cd32,
linen: 0xfaf0e6,
magenta: 0xff00ff,
maroon: 0x800000,
mediumaquamarine: 0x66cdaa,
mediumblue: 0x0000cd,
mediumorchid: 0xba55d3,
mediumpurple: 0x9370db,
mediumseagreen: 0x3cb371,
mediumslateblue: 0x7b68ee,
mediumspringgreen: 0x00fa9a,
mediumturquoise: 0x48d1cc,
mediumvioletred: 0xc71585,
midnightblue: 0x191970,
mintcream: 0xf5fffa,
mistyrose: 0xffe4e1,
moccasin: 0xffe4b5,
navajowhite: 0xffdead,
navy: 0x000080,
oldlace: 0xfdf5e6,
olive: 0x808000,
olivedrab: 0x6b8e23,
orange: 0xffa500,
orangered: 0xff4500,
orchid: 0xda70d6,
palegoldenrod: 0xeee8aa,
palegreen: 0x98fb98,
paleturquoise: 0xafeeee,
palevioletred: 0xdb7093,
papayawhip: 0xffefd5,
peachpuff: 0xffdab9,
peru: 0xcd853f,
pink: 0xffc0cb,
plum: 0xdda0dd,
powderblue: 0xb0e0e6,
purple: 0x800080,
rebeccapurple: 0x663399,
red: 0xff0000,
rosybrown: 0xbc8f8f,
royalblue: 0x4169e1,
saddlebrown: 0x8b4513,
salmon: 0xfa8072,
sandybrown: 0xf4a460,
seagreen: 0x2e8b57,
seashell: 0xfff5ee,
sienna: 0xa0522d,
silver: 0xc0c0c0,
skyblue: 0x87ceeb,
slateblue: 0x6a5acd,
slategray: 0x708090,
slategrey: 0x708090,
snow: 0xfffafa,
springgreen: 0x00ff7f,
steelblue: 0x4682b4,
tan: 0xd2b48c,
teal: 0x008080,
thistle: 0xd8bfd8,
tomato: 0xff6347,
turquoise: 0x40e0d0,
violet: 0xee82ee,
wheat: 0xf5deb3,
white: 0xffffff,
whitesmoke: 0xf5f5f5,
yellow: 0xffff00,
yellowgreen: 0x9acd32
})
);
const systemColors = new Map(
Object.entries({
"ActiveBorder": 0x3b99fc,
"ActiveCaption": 0x000000,
"AppWorkspace": 0xaaaaaa,
"Background": 0x6363ce,
"ButtonFace": 0xffffff,
"ButtonHighlight": 0xe9e9e9,
"ButtonShadow": 0x9fa09f,
"ButtonText": 0x000000,
"CaptionText": 0x000000,
"GrayText": 0x7f7f7f,
"Highlight": 0xb2d7ff,
"HighlightText": 0x000000,
"InactiveBorder": 0xffffff,
"InactiveCaption": 0xffffff,
"InactiveCaptionText": 0x000000,
"InfoBackground": 0xfbfcc5,
"InfoText": 0x000000,
"Menu": 0xf6f6f6,
"MenuText": 0xffffff,
"Scrollbar": 0xaaaaaa,
"ThreeDDarkShadow": 0x000000,
"ThreeDFace": 0xc0c0c0,
"ThreeDHighlight": 0xffffff,
"ThreeDLightShadow": 0xffffff,
"ThreeDShadow": 0x000000,
"Window": 0xececec,
"WindowFrame": 0xaaaaaa,
"WindowText": 0x000000,
"-webkit-focus-ring-color": 0xe59700
}).map(([key, value]) => [key.toLowerCase(), value])
);
function getSRGBLightness(r, g, b) {
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
}
let canvas$1;
let context$1;
function domParseColor($color) {
if (!context$1) {
canvas$1 = document.createElement("canvas");
canvas$1.width = 1;
canvas$1.height = 1;
context$1 = canvas$1.getContext("2d", {willReadFrequently: true});
}
context$1.fillStyle = $color;
context$1.fillRect(0, 0, 1, 1);
const d = context$1.getImageData(0, 0, 1, 1).data;
const color = `rgba(${d[0]}, ${d[1]}, ${d[2]}, ${(d[3] / 255).toFixed(2)})`;
return parseRGB(color);
}
function throttle(callback) {
let pending = false;
let frameId = null;
let lastArgs;
const throttled = (...args) => {
lastArgs = args;
if (frameId) {
pending = true;
} else {
callback(...lastArgs);
frameId = requestAnimationFrame(() => {
frameId = null;
if (pending) {
callback(...lastArgs);
pending = false;
}
});
}
};
const cancel = () => {
cancelAnimationFrame(frameId);
pending = false;
frameId = null;
};
return Object.assign(throttled, {cancel});
}
function createAsyncTasksQueue() {
const tasks = [];
let frameId = null;
function runTasks() {
let task;
while ((task = tasks.shift())) {
task();
}
frameId = null;
}
function add(task) {
tasks.push(task);
if (!frameId) {
frameId = requestAnimationFrame(runTasks);
}
}
function cancel() {
tasks.splice(0);
cancelAnimationFrame(frameId);
frameId = null;
}
return {add, cancel};
}
const delayTokens = new Set();
function requestAnimationFrameOnce(token, callback) {
if (delayTokens.has(token)) {
return;
}
delayTokens.add(token);
requestAnimationFrame(() => {
delayTokens.delete(token);
callback();
});
}
function hexify(number) {
return (number < 16 ? "0" : "") + number.toString(16);
}
function generateUID() {
if ("randomUUID" in crypto) {
const uuid = crypto.randomUUID();
return (
uuid.substring(0, 8) +
uuid.substring(9, 13) +
uuid.substring(14, 18) +
uuid.substring(19, 23) +
uuid.substring(24)
);
}
if ("getRandomValues" in crypto) {
return Array.from(crypto.getRandomValues(new Uint8Array(16)))
.map((x) => hexify(x))
.join("");
}
return Math.floor(Math.random() * 2 ** 55).toString(36);
}
let documentVisibilityListener = null;
let documentIsVisible_ = !document.hidden;
const listenerOptions = {
capture: true,
passive: true
};
function watchForDocumentVisibility() {
document.addEventListener(
"visibilitychange",
documentVisibilityListener,
listenerOptions
);
window.addEventListener(
"pageshow",
documentVisibilityListener,
listenerOptions
);
window.addEventListener(
"focus",
documentVisibilityListener,
listenerOptions
);
}
function stopWatchingForDocumentVisibility() {
document.removeEventListener(
"visibilitychange",
documentVisibilityListener,
listenerOptions
);
window.removeEventListener(
"pageshow",
documentVisibilityListener,
listenerOptions
);
window.removeEventListener(
"focus",
documentVisibilityListener,
listenerOptions
);
}
function setDocumentVisibilityListener(callback) {
const alreadyWatching = Boolean(documentVisibilityListener);
documentVisibilityListener = () => {
if (!document.hidden) {
removeDocumentVisibilityListener();
callback();
documentIsVisible_ = true;
}
};
if (!alreadyWatching) {
watchForDocumentVisibility();
}
}
function removeDocumentVisibilityListener() {
stopWatchingForDocumentVisibility();
documentVisibilityListener = null;
}
function documentIsVisible() {
return documentIsVisible_;
}
function getDuration(time) {
let duration = 0;
if (time.seconds) {
duration += time.seconds * 1000;
}
if (time.minutes) {
duration += time.minutes * 60 * 1000;
}
if (time.hours) {
duration += time.hours * 60 * 60 * 1000;
}
if (time.days) {
duration += time.days * 24 * 60 * 60 * 1000;
}
return duration;
}
function logInfo(...args) {}
function logWarn(...args) {}
function logAssert(...args) {}
function ASSERT(description, condition) {
if (!condition) {
logAssert(description);
}
}
function removeNode(node) {
node && node.parentNode && node.parentNode.removeChild(node);
}
function watchForNodePosition(node, mode, onRestore = Function.prototype) {
const MAX_ATTEMPTS_COUNT = 10;
const RETRY_TIMEOUT = getDuration({seconds: 2});
const ATTEMPTS_INTERVAL = getDuration({seconds: 10});
let prevSibling = node.previousSibling;
let parent = node.parentNode;
if (!parent) {
throw new Error(
"Unable to watch for node position: parent element not found"
);
}
if (mode === "prev-sibling" && !prevSibling) {
throw new Error(
"Unable to watch for node position: there is no previous sibling"
);
}
let attempts = 0;
let start = null;
let timeoutId = null;
const restore = throttle(() => {
if (timeoutId) {
return;
}
attempts++;
const now = Date.now();
if (start == null) {
start = now;
} else if (attempts >= MAX_ATTEMPTS_COUNT) {
if (now - start < ATTEMPTS_INTERVAL) {
logWarn(
`Node position watcher paused: retry in ${RETRY_TIMEOUT}ms`,
node,
prevSibling
);
timeoutId = setTimeout(() => {
start = null;
attempts = 0;
timeoutId = null;
restore();
}, RETRY_TIMEOUT);
return;
}
start = now;
attempts = 1;
}
if (mode === "head") {
if (prevSibling && prevSibling.parentNode !== parent) {
logWarn(
"Sibling moved, moving node to the head end",
node,
prevSibling,
parent
);
prevSibling = document.head.lastChild;
}
}
if (mode === "prev-sibling") {
if (prevSibling.parentNode == null) {
logWarn(
"Unable to restore node position: sibling was removed",
node,
prevSibling,
parent
);
stop();
return;
}
if (prevSibling.parentNode !== parent) {
logWarn(
"Style was moved to another parent",
node,
prevSibling,
parent
);
updateParent(prevSibling.parentNode);
}
}
if (mode === "head" && !parent.isConnected) {
parent = document.head;
}
logWarn("Restoring node position", node, prevSibling, parent);
parent.insertBefore(
node,
prevSibling && prevSibling.isConnected
? prevSibling.nextSibling
: parent.firstChild
);
observer.takeRecords();
onRestore && onRestore();
});
const observer = new MutationObserver(() => {
if (
(mode === "head" &&
(node.parentNode !== parent || !node.parentNode.isConnected)) ||
(mode === "prev-sibling" && node.previousSibling !== prevSibling)
) {
restore();
}
});
const run = () => {
observer.observe(parent, {childList: true});
};
const stop = () => {
clearTimeout(timeoutId);
observer.disconnect();
restore.cancel();
};
const skip = () => {
observer.takeRecords();
};
const updateParent = (parentNode) => {
parent = parentNode;
stop();
run();
};
run();
return {run, stop, skip};
}
function iterateShadowHosts(root, iterator) {
if (root == null) {
return;
}
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
acceptNode(node) {