start adding a custom client mod

This commit is contained in:
murdle 2025-12-12 01:41:33 +02:00
parent f577604ae8
commit 42bcfd0a6d
2269 changed files with 554 additions and 115 deletions

View File

@ -0,0 +1,69 @@
function checkServiceWorkerSupport() {
if (!"serviceWorker" in navigator || !"PushManager" in window)
throw new Error("Your browser does not have Service Worker support")
}
async function unregisterPush() {
checkServiceWorkerSupport();
const registration = await navigator.serviceWorker.getRegistration();
if (!registration) return;
const subscription = await reg.pushManager.getSubscription();
if (!subscription) return;
await subscription.unsubscribe();
}
async function registerPush(publicKey) {
checkServiceWorkerSupport();
const registration = await navigator.serviceWorker.register("/assets/custom/serviceWorker.js");
console.log("Service Worker registered");
let subscription = await registration.pushManager.getSubscription();
if (!subscription) {
const applicationServerKey = urlBase64ToUint8Array(publicKey);
subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey
});
console.log("Push subscription obtained");
}
const response = await fetch(`${window.GLOBAL_ENV.API_ENDPOINT}/v9/users/@me/devices`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": localStorage.token
},
body: JSON.stringify({
provider: "webpush",
webpush_subscription: subscription
})
});
if (response.ok) {
console.log("Device registered successfully");
} else {
const text = await response.text();
throw new Error("Failed to register: ", text)
}
}
function urlBase64ToUint8Array(base64String) {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; i++) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}

View File

@ -0,0 +1,67 @@
let fingerprint = null;
const OriginalRTC = window.RTCPeerConnection;
const OriginalSend = WebSocket.prototype.send;
window.RTCPeerConnection = function (...args) {
const pc = new OriginalRTC(...args);
const originalCreateOffer = pc.createOffer.bind(pc);
pc.createOffer = async function (options) {
const offer = await originalCreateOffer(options);
if (offer.sdp) {
const lines = offer.sdp.split("\n");
for (const line of lines) {
if (line.includes("a=fingerprint")) {
fingerprint = line.split("a=fingerprint:")[1]?.trim() ?? null;
}
}
}
return offer;
};
return pc;
};
Object.setPrototypeOf(window.RTCPeerConnection, OriginalRTC);
Object.setPrototypeOf(window.RTCPeerConnection.prototype, OriginalRTC.prototype);
WebSocket.prototype.send = function (data) {
try {
let parsed = JSON.parse(data);
if (parsed.d && typeof parsed.d === "object") {
for (const [key, value] of Object.entries(parsed.d)) {
if (typeof value === "string" && (value.includes("a=extmap") || value.includes("a=ice-") || value.includes("a=rtpmap"))) {
if (!value.includes("a=fingerprint")) {
parsed.d[key] = addFingerprintToSdp(value);
}
}
}
return OriginalSend.call(this, JSON.stringify(parsed));
}
} catch (e) {}
return OriginalSend.call(this, data);
};
function addFingerprintToSdp(sdp) {
if (!fingerprint) return sdp;
const lines = sdp.split("\n");
const result = [];
let added = false;
for (const line of lines) {
result.push(line);
if (!added && line.includes("a=ice-pwd:")) {
result.push(`a=fingerprint:${fingerprint}`);
added = true;
}
}
return result.join("\n");
}

View File

@ -1,4 +1,4 @@
self.addEventListener('push', (event) => {
self.addEventListener("push", (event) => {
if (!event.data) return;
const payload = event.data.json();
@ -18,7 +18,7 @@ self.addEventListener('push', (event) => {
event.waitUntil(self.registration.showNotification(title, options));
});
self.addEventListener('notificationclick', (event) => {
self.addEventListener("notificationclick", (event) => {
event.notification.close();
const payload = event.notification.data;

View File

@ -0,0 +1,120 @@
(function () {
const BUTTON_ID = "rscord-settings-btn";
const CONTENT_CONTAINER_ID = "custom-content";
const SWITCH_CONTAINER_ID = "switch-container";
const CSS_CLASSES = {
tabItem: "item-3XjbnG",
selected: "selected-g-kMVV",
contentColumn: "contentColumn-1C7as6",
settingsSidebar: "standardSidebarView-E9Pc3j",
title: "colorStandard-1Xxp1s size14-k_3Hy4 h1-34Txb0 title-3hptVQ defaultColor-2cKwKo defaultMarginh1-EURXsm"
};
const TAB_CONTENT = `
<h2 class="${CSS_CLASSES.title}">RSCord Settings</h2>
<div id="${SWITCH_CONTAINER_ID}"></div>
`;
function addSwitches(container) {
container.appendChild(createSwitch(
"Push Notifications",
"Sends you notifications even when you close the app",
"push-notifications",
false,
async () => {
const publicKey = window.GLOBAL_ENV.VAPID_KEY;
if (!publicKey) {
alert("Server has not enabled push notifications")
return false;
}
try {
await registerPush(publicKey);
return true;
} catch(err) {
alert(err.message);
return false;
}
}
));
}
function addSettingsTab() {
const advancedTab = document.querySelector(`.${CSS_CLASSES.tabItem}[aria-controls='advanced-tab']`);
if (!advancedTab) return;
if (document.getElementById(BUTTON_ID)) return;
const settingsBtn = document.createElement("div");
settingsBtn.id = BUTTON_ID;
settingsBtn.className = advancedTab.className;
settingsBtn.role = "tab";
settingsBtn.tabIndex = -1;
settingsBtn.ariaSelected = "false";
settingsBtn.textContent = "RSCord Settings";
settingsBtn.addEventListener("click", () => {
const tabs = settingsBtn.parentElement.querySelectorAll('[role="tab"]');
tabs.forEach(tab => tab.classList.remove(CSS_CLASSES.selected));
tabs.forEach(tab => tab.setAttribute("aria-selected", "false"));
settingsBtn.classList.add(CSS_CLASSES.selected);
settingsBtn.setAttribute("aria-selected", "true");
let customContent = document.getElementById(CONTENT_CONTAINER_ID);
if (!customContent) {
customContent = document.createElement("div");
customContent.id = CONTENT_CONTAINER_ID;
customContent.innerHTML = TAB_CONTENT;
const switchContainer = customContent.querySelector(`#${SWITCH_CONTAINER_ID}`);
addSwitches(switchContainer);
document.querySelector(`.${CSS_CLASSES.contentColumn}`).appendChild(customContent);
}
const contentColumn = document.querySelector(`.${CSS_CLASSES.contentColumn}`);
Array.from(contentColumn.children).forEach(child => {
if (child.id !== CONTENT_CONTAINER_ID) child.style.display = "none";
});
customContent.style.display = "block";
});
advancedTab.insertAdjacentElement("afterend", settingsBtn);
return true;
}
function startObserver() {
const observer = new MutationObserver(() => {
const sidebar = document.querySelector(`.${CSS_CLASSES.settingsSidebar}`);
if (sidebar) addSettingsTab();
});
observer.observe(document.body, { childList: true, subtree: true });
}
startObserver();
document.body.addEventListener("click", (e) => {
const clickedTab = e.target.closest('[role="tab"]');
if (!clickedTab) return;
const allTabs = document.querySelectorAll('[role="tab"]');
allTabs.forEach(tab => tab.classList.remove(CSS_CLASSES.selected));
allTabs.forEach(tab => tab.setAttribute("aria-selected", "false"));
clickedTab.classList.add(CSS_CLASSES.selected);
clickedTab.setAttribute("aria-selected", "true");
const contentColumn = document.querySelector(`.${CSS_CLASSES.contentColumn}`);
if (!contentColumn) return;
if (clickedTab.id === BUTTON_ID) {
Array.from(contentColumn.children).forEach(child => {
if (child.id === CONTENT_CONTAINER_ID) child.style.display = "block";
else child.style.display = "none";
});
} else {
Array.from(contentColumn.children).forEach(child => {
if (child.id !== CONTENT_CONTAINER_ID) child.style.display = "";
else child.style.display = "none";
});
}
});
})();

View File

@ -0,0 +1,197 @@
const CSS_CLASSES = {
container: "container-1zDvAE",
labelRow: "labelRow-2jl9gK",
label: "title-2dsDLn",
control: "control-1fl03-",
switchControl: "container-2nx-BQ",
switchControlChecked: "checked-25WXMf",
input: "input-2XRLou",
slider: "slider-32CRPX",
note: "note-2C4pGr",
description: "colorStandard-1Xxp1s size14-k_3Hy4 description-30xx7u formText-2ngGjI modeDefault-2fEh7a",
divider: "divider-_0um2u dividerDefault-3C2-ws"
};
const ICON_PATHS = {
checked: [
"M7.89561 14.8538L6.30462 13.2629L14.3099 5.25755L15.9009 6.84854L7.89561 14.8538Z",
"M4.08643 11.0903L5.67742 9.49929L9.4485 13.2704L7.85751 14.8614L4.08643 11.0903Z"
],
unchecked: [
"M5.13231 6.72963L6.7233 5.13864L14.855 13.2704L13.264 14.8614L5.13231 6.72963Z",
"M13.2704 5.13864L14.8614 6.72963L6.72963 14.8614L5.13864 13.2704L13.2704 5.13864Z"
]
};
const CHECKED_COLOR = "hsl(139, 47.3%, 43.9%)";
const UNCHECKED_COLOR = "hsl(218, 4.6%, 46.9%)";
function createSwitch(
labelText,
descriptionText,
inputId,
defaultChecked = false,
onToggle = null
) {
const container = document.createElement("div");
container.className = CSS_CLASSES.container;
const checkbox = document.createElement("input");
checkbox.id = inputId;
checkbox.type = "checkbox";
checkbox.className = CSS_CLASSES.input;
checkbox.tabIndex = 0;
checkbox.checked = defaultChecked;
const sliderSVG = createSliderSVG(defaultChecked);
const switchControl = document.createElement("div");
switchControl.className = `${CSS_CLASSES.switchControl} ${defaultChecked ? CSS_CLASSES.switchControlChecked : ""}`;
switchControl.style.opacity = "1";
switchControl.style.backgroundColor = defaultChecked ? CHECKED_COLOR : UNCHECKED_COLOR;
switchControl.style.cursor = "pointer";
switchControl.tabIndex = -1;
switchControl.appendChild(sliderSVG);
switchControl.appendChild(checkbox);
const controlWrapper = document.createElement("div");
controlWrapper.className = CSS_CLASSES.control;
controlWrapper.appendChild(switchControl);
const label = document.createElement("label");
label.htmlFor = inputId;
label.className = CSS_CLASSES.label;
label.textContent = labelText;
const labelRow = document.createElement("div");
labelRow.className = CSS_CLASSES.labelRow;
labelRow.appendChild(label);
labelRow.appendChild(controlWrapper);
container.appendChild(labelRow);
if (descriptionText) {
const description = document.createElement("div");
description.className = CSS_CLASSES.description;
description.textContent = descriptionText;
const noteWrapper = document.createElement("div");
noteWrapper.className = CSS_CLASSES.note;
noteWrapper.appendChild(description);
container.appendChild(noteWrapper);
}
const divider = document.createElement("div");
divider.className = CSS_CLASSES.divider;
container.appendChild(divider);
const updateSwitch = (checked) => {
switchControl.classList.toggle(CSS_CLASSES.switchControlChecked, checked);
switchControl.style.backgroundColor = checked ? CHECKED_COLOR : UNCHECKED_COLOR;
sliderSVG.style.left = checked ? "12px" : "-3px";
updateSVGIcon(sliderSVG, checked);
};
const handleToggle = async () => {
const prev = !checkbox.checked;
if (typeof onToggle === "function") {
const ret = await onToggle(checkbox.checked);
if (ret === false) checkbox.checked = prev;
}
updateSwitch(checkbox.checked);
};
switchControl.addEventListener("click", (e) => {
if (e.target === checkbox) return;
e.preventDefault();
e.stopPropagation();
checkbox.checked = !checkbox.checked;
checkbox.dispatchEvent(new Event("change", { bubbles: true }));
});
checkbox.addEventListener("click", (e) => {
e.stopPropagation();
});
checkbox.addEventListener("change", handleToggle);
return container;
}
function createSliderSVG(isChecked) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("class", CSS_CLASSES.slider);
svg.setAttribute("viewBox", "0 0 28 20");
svg.setAttribute("preserveAspectRatio", "xMinYMid meet");
svg.style.left = isChecked ? "12px" : "-3px";
svg.style.position = "absolute";
svg.style.transition = "left 0.2s";
const circle = document.createElementNS("http://www.w3.org/2000/svg", "rect");
circle.setAttribute("fill", "white");
circle.setAttribute("x", "4");
circle.setAttribute("y", "0");
circle.setAttribute("height", "20");
circle.setAttribute("width", "20");
circle.setAttribute("rx", "10");
svg.appendChild(circle);
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
icon.setAttribute("viewBox", "0 0 20 20");
icon.setAttribute("fill", "none");
const color = isChecked ? CHECKED_COLOR : UNCHECKED_COLOR;
if (isChecked) {
const checkPaths = [
"M7.89561 14.8538L6.30462 13.2629L14.3099 5.25755L15.9009 6.84854L7.89561 14.8538Z",
"M4.08643 11.0903L5.67742 9.49929L9.4485 13.2704L7.85751 14.8614L4.08643 11.0903Z"
];
checkPaths.forEach(d => {
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("fill", color);
path.setAttribute("d", d);
icon.appendChild(path);
});
} else {
const xPaths = [
"M5.13231 6.72963L6.7233 5.13864L14.855 13.2704L13.264 14.8614L5.13231 6.72963Z",
"M13.2704 5.13864L14.8614 6.72963L6.72963 14.8614L5.13864 13.2704L13.2704 5.13864Z"
];
xPaths.forEach(d => {
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("fill", color);
path.setAttribute("d", d);
icon.appendChild(path);
});
}
svg.appendChild(icon);
return svg;
}
function createSVGIcon(parentSVG, isChecked) {
const color = isChecked ? CHECKED_COLOR : UNCHECKED_COLOR;
const paths = ICON_PATHS[isChecked ? "checked" : "unchecked"];
const icon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
icon.setAttribute("viewBox", "0 0 20 20");
icon.setAttribute("fill", "none");
paths.forEach(d => {
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("fill", color);
path.setAttribute("d", d);
icon.appendChild(path);
});
parentSVG.appendChild(icon);
}
function updateSVGIcon(sliderSVG, isChecked) {
const oldIcon = sliderSVG.querySelector("svg svg");
if (oldIcon) {
oldIcon.remove();
}
createSVGIcon(sliderSVG, isChecked);
}

View File

@ -29,8 +29,8 @@
window.__BILLING_STANDALONE__ = /^\/billing/.test(location.pathname)
function protocolRelative(url) {
if (!url) return '';
return '//' + url.replace(/^https?:\/\//, '').replace(/\/$/, '');
if (!url) return "";
return "//" + url.replace(/^https?:\/\//, "").replace(/\/$/, "");
}
async function loadGlobalEnv() {
@ -45,137 +45,70 @@
CDN_HOST: protocolRelative(data.cdn.baseUrl),
ASSET_ENDPOINT: protocolRelative(data.cdn.baseUrl),
MEDIA_PROXY_ENDPOINT: protocolRelative(data.cdn.baseUrl),
WIDGET_ENDPOINT: '//discord.com/widget',
INVITE_HOST: 'discord.gg',
GUILD_TEMPLATE_HOST: 'discord.new',
GIFT_CODE_HOST: 'discord.gift',
RELEASE_CHANNEL: 'stable',
WIDGET_ENDPOINT: "//discord.com/widget",
INVITE_HOST: "discord.gg",
GUILD_TEMPLATE_HOST: "discord.new",
GIFT_CODE_HOST: "discord.gift",
RELEASE_CHANNEL: "stable",
MARKETING_ENDPOINT: protocolRelative(data.api.baseUrl),
BRAINTREE_KEY: 'production_5st77rrc_49pp2rp4phym7387',
STRIPE_KEY: 'pk_live_CUQtlpQUF0vufWpnpUmQvcdi',
BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387",
STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi",
NETWORKING_ENDPOINT: protocolRelative(data.api.baseUrl),
RTC_LATENCY_ENDPOINT: protocolRelative(data.api.baseUrl),
ACTIVITY_APPLICATION_HOST: protocolRelative(data.api.baseUrl),
PROJECT_ENV: 'production',
REMOTE_AUTH_ENDPOINT: '//remote-auth-gateway.discord.gg',
SENTRY_TAGS: { buildId: '9af39da', buildType: 'normal' },
PROJECT_ENV: "production",
REMOTE_AUTH_ENDPOINT: "//remote-auth-gateway.discord.gg",
SENTRY_TAGS: { buildId: "9af39da", buildType: "normal" },
MIGRATION_SOURCE_ORIGIN: protocolRelative(data.api.baseUrl),
MIGRATION_DESTINATION_ORIGIN: protocolRelative(data.api.baseUrl),
HTML_TIMESTAMP: Date.now(),
ALGOLIA_KEY: 'aca0d7082e4e63af5ba5917d5e96bed0',
GATEWAY_URL: data.gateway.baseUrl
ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0",
GATEWAY_URL: data.gateway.baseUrl,
VAPID_KEY: data.vapid.publicKey
};
const customScripts = [
"/assets/custom/pushMessages.js",
"/assets/custom/rtcPatcher.js",
"/assets/custom/web/switch.js",
"/assets/custom/web/main.js",
]
const normalScripts = [
"/assets/053574d0f6edc579c71e.js",
"/assets/771dcd97bfd5f9b77ef6.js",
"/assets/0ffb9e3c90aa88720fc7.js",
"/assets/cbc98c97c3635bf34da3.js",
];
const scripts = [
'/assets/053574d0f6edc579c71e.js',
'/assets/771dcd97bfd5f9b77ef6.js',
'/assets/0ffb9e3c90aa88720fc7.js',
'/assets/cbc98c97c3635bf34da3.js'
...normalScripts,
...customScripts
];
scripts.forEach(src => {
const s = document.createElement('script');
const s = document.createElement("script");
s.src = src;
s.defer = true;
document.body.appendChild(s);
});
} catch (e) {
console.error('Failed to load GLOBAL_ENV', e);
console.error("Failed to load GLOBAL_ENV", e);
}
}
localStorage.setItem("exerimentOverrides", JSON.stringify({
"2022-03_text_in_voice": {
type: "guild",
revision: 1,
bucket: 1,
override: true
}
}));
loadGlobalEnv();
})();
</script>
<script>
(function() {
let lastCredentials = null;
const OriginalRTC = window.RTCPeerConnection;
window.RTCPeerConnection = function(...args) {
const pc = new OriginalRTC(...args);
const originalCreateOffer = pc.createOffer.bind(pc);
pc.createOffer = async function(options) {
const offer = await originalCreateOffer(options);
if (offer.sdp) {
const lines = offer.sdp.split('\n');
for (const line of lines) {
if (line.includes('a=fingerprint')) {
const fp = line.split('a=fingerprint:')[1]?.trim();
if (fp) {
lastCredentials = lastCredentials || {};
lastCredentials.fingerprint = fp;
}
}
}
}
return offer;
};
return pc;
};
Object.setPrototypeOf(window.RTCPeerConnection, OriginalRTC);
Object.setPrototypeOf(window.RTCPeerConnection.prototype, OriginalRTC.prototype);
const OriginalSend = WebSocket.prototype.send;
WebSocket.prototype.send = function(data) {
try {
let parsed = JSON.parse(data);
if (parsed.d && typeof parsed.d === 'object') {
for (const [key, value] of Object.entries(parsed.d)) {
if (typeof value === 'string' && (value.includes('a=extmap') || value.includes('a=ice-') || value.includes('a=rtpmap'))) {
if (!value.includes('a=fingerprint')) {
parsed.d[key] = addFingerprintToSdp(value);
}
}
}
return OriginalSend.call(this, JSON.stringify(parsed));
}
} catch (e) {}
return OriginalSend.call(this, data);
};
function addFingerprintToSdp(sdp) {
const fingerprint = lastCredentials?.fingerprint;
if (!fingerprint) return sdp;
const lines = sdp.split('\n');
const result = [];
let added = false;
for (const line of lines) {
result.push(line);
if (!added && line.includes('a=ice-pwd:')) {
result.push(`a=fingerprint:${fingerprint}`);
added = true;
}
}
return result.join('\n');
}
})();
</script>
<script>
(function() {
localStorage.setItem("exerimentOverrides", JSON.stringify({
"2022-03_text_in_voice": {
type: "guild",
revision: 1,
bucket: 1,
override: true
}
}));
})();
</script>
</head>
<body>
<div id="app-mount"></div>

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 707 B

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 271 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 769 B

After

Width:  |  Height:  |  Size: 769 B

View File

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 501 B

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 568 B

After

Width:  |  Height:  |  Size: 568 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 563 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View File

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 814 B

View File

Before

Width:  |  Height:  |  Size: 368 B

After

Width:  |  Height:  |  Size: 368 B

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

View File

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

View File

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 489 B

View File

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 1004 B

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 594 B

View File

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 239 B

View File

Before

Width:  |  Height:  |  Size: 584 B

After

Width:  |  Height:  |  Size: 584 B

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 815 B

After

Width:  |  Height:  |  Size: 815 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 857 B

View File

Before

Width:  |  Height:  |  Size: 942 B

After

Width:  |  Height:  |  Size: 942 B

View File

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 555 B

View File

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 1010 B

View File

Before

Width:  |  Height:  |  Size: 614 B

After

Width:  |  Height:  |  Size: 614 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 633 B

View File

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 439 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 640 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 937 B

After

Width:  |  Height:  |  Size: 937 B

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 565 B

Some files were not shown because too many files have changed in this diff Show More