Compare commits

..
38 Commits
Author SHA1 Message Date
polv 55c4d094ee add video 2026-10-30 19:30:40 +07:00
polv 13091adc4d add video 2026-10-29 18:39:26 +07:00
polv 483ea5148b add video 2026-10-17 02:12:27 +07:00
polv f065052213 add video 2026-10-06 22:28:56 +07:00
polv b71eaf390c add video 2026-10-04 12:30:17 +07:00
polv 64d27f57ff add video 2026-10-04 12:18:54 +07:00
polv e776c57030 trailing... fix; add video 2026-09-29 16:39:58 +07:00
polv 8ba15c9126 add video 2026-09-24 08:48:40 +07:00
polv db9c7e09b9 auto-fullscreen video on landscape 2026-09-23 23:26:29 +07:00
polv 4dc179a7d2 desktop offline mode first 2026-09-23 21:17:28 +07:00
polv d9777c3c82 YouTube JS API seek 2026-09-23 21:05:12 +07:00
polv 218ba874f9 add video 2026-09-23 20:13:56 +07:00
polv b3f24f5911 add video 2026-09-10 21:13:43 +07:00
polv abebf72ce1 add video 2026-09-02 23:23:49 +07:00
polv 94c9f67ce1 add video 2026-08-23 08:21:23 +07:00
polv 5aa65c86ea add video 2026-08-06 08:45:29 +07:00
polv 58b01b77fb fix filename for a new video strip 2026-08-05 08:52:51 +07:00
polv 720a49f544 add video 2026-08-05 08:46:25 +07:00
polv d8c5dc964f add video 2026-08-02 11:21:38 +07:00
polv 36c44873a2 add css for mobile 2026-07-28 14:08:06 +07:00
polv 23e4be8b15 Merge pull request 'feat/tauri-mobile' (#1) from feat/tauri-mobile into main
Reviewed-on: #1
2026-07-28 06:55:00 +00:00
polv f4a0c8d883 build with redirected images 2026-07-28 13:53:21 +07:00
polv 5a8edf9330 add images to git 2026-07-28 13:20:46 +07:00
polv 412905ade6 add video 2026-07-28 12:12:59 +07:00
polv 3937086dbe add video 2026-07-28 11:57:30 +07:00
polv 92173199c9 add video and test dedup 2026-07-17 18:21:18 +07:00
polv c475960219 add video to mobile via YouTube 2026-07-15 23:05:19 +07:00
polv 8e6c5e2bda image compression 2026-07-13 20:12:51 +07:00
polv e76a45f1d6 add video 2026-07-13 17:16:44 +07:00
polv d632c946e4 add video; fix group-similar.js for public folder 2026-07-13 17:02:35 +07:00
polv 05e45cd936 add video and some fixes 2026-07-01 21:47:34 +07:00
polv 40edfe44e9 add Android build; remove bulk video compression as it's impractical 2026-06-27 19:52:00 +07:00
polv f2f6c28989 tauri build fails of large vdo 2026-06-26 00:25:35 +07:00
polv 87a3c1b641 video compress to webm 2026-06-25 17:56:03 +07:00
polv d72377b0bb ensure it builds 2026-06-25 16:51:22 +07:00
polv 3df6d87ab5 convert all images to webp 2026-06-25 16:34:27 +07:00
polv 3e3d2dcbcb tauri to manage and kill ws-server 2026-06-25 15:18:23 +07:00
polv 126a3749f9 add tauri 2026-06-25 13:18:21 +07:00
24803 changed files with 90702 additions and 10358 deletions

No files matched your search

+2 -1
View File
@@ -1 +1,2 @@
node_modules
node_modules
.env
+4
View File
@@ -6,6 +6,10 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.maxTokenizationLineLength": 2500,
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"[vue]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
+5 -3
View File
@@ -89,9 +89,11 @@ docs/ # VitePress documentation root
Downloader.vue # Vue component for entering a video filename (web interface / video input UI)
Video.vue # Vue component to display videos and linked timestamps
public/ # Directory to put downloaded videos
*.md # Markdown files with content
[video-filename]/ # Screenshot folders (auto-generated)
*.png # Timestamped screenshots
images/
[video-filename]/ # Screenshot folders (auto-generated)
*.webp # Timestamped screenshots
[video-filename].webm # Downloaded videos
[video-filename].md # Markdown files with content
server.js # WebSocket server for handling downloads
group-similar.js # Script for deduplicating similar screenshots
```
+93
View File
@@ -0,0 +1,93 @@
import fs from "node:fs/promises";
import path from "node:path";
import sharp from "sharp";
const SRC_DIR = path.resolve("docs/public"); // change if needed
const OUT_DIR = path.resolve("docs/public/images"); // change if needed
const MAX_W = 800;
const MAX_H = 600;
const FORMAT = "webp";
const WEBP_QUALITY = 75; // tweak 60-85 if you want smaller/larger
async function walk(dir) {
const entries = await fs.readdir(dir, { withFileTypes: true });
console.log(dir, entries.filter((e) => !e.isDirectory()).length);
const files = [];
for (const e of entries) {
const p = path.join(dir, e.name);
if (p === OUT_DIR) continue;
if (e.isDirectory()) files.push(...(await walk(p)));
else files.push(p);
}
return files;
}
function isImage(file) {
return /\.(png|jpe?g|webp|avif)$/i.test(file);
}
async function ensureDir(p) {
await fs.mkdir(p, { recursive: true });
}
async function processOne(inPath, outPathBase) {
await ensureDir(path.dirname(outPathBase));
await sharp(inPath)
.rotate() // respects EXIF orientation
.resize({
width: MAX_W,
height: MAX_H,
fit: "inside", // preserve aspect, fit within box
withoutEnlargement: true, // don't upscale small images
})
.toFormat(FORMAT, {
quality: WEBP_QUALITY,
effort: 4,
})
.toFile(`${outPathBase}.${FORMAT}`);
}
async function main() {
const files = (await walk(SRC_DIR)).filter(isImage);
await ensureDir(OUT_DIR);
let done = 0;
for (const inPath of files) {
const rel = path.relative(SRC_DIR, inPath);
// strip original extension and write same relative path
const outBase = path
.join(OUT_DIR, rel)
.replace(/\.(png|jpe?g|webp|avif)$/i, "");
const outPath = `${outBase}.${FORMAT}`;
// simple cache: skip if output exists and is newer than input
try {
const [stIn, stOut] = await Promise.all([
fs.stat(inPath),
fs.stat(outPath),
]);
if (stOut.mtimeMs >= stIn.mtimeMs) continue;
} catch {
// output missing -> process
}
await processOne(inPath, outBase);
done++;
}
console.log(
`Optimized ${done} image(s) to max ${MAX_W}x${MAX_H} (${FORMAT}).`,
);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});
-2
View File
@@ -1,2 +0,0 @@
**/*.png
**/*.jpg
+1
View File
@@ -1,2 +1,3 @@
/dist
/cache
/.temp
+82 -14
View File
@@ -1,46 +1,114 @@
import { defineConfig } from 'vitepress'
import { defineConfig } from "vitepress";
import { execSync } from "node:child_process";
const TAURI_HOST = ''
const host = process.env.TAURI_DEV_HOST;
const {
IMG_ORIGIN = `https://git.polv.cc/polv/yt2press/raw/branch/${execSync(
"git branch --show-current",
)
.toString()
.trimEnd()}/docs/public`,
} = process.env;
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "yt2press",
description: "video to vitepress",
head: [
[
"script",
{
async: "async",
src: "https://www.youtube.com/iframe_api",
},
],
],
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: 'Home', link: '/' },
],
nav: [{ text: "Home", link: "/" }],
sidebar: [
{
text: 'Preview',
text: "Preview",
// items: [
// { text: 'Markdown Examples', link: '/markdown-examples' },
// { text: 'Runtime API Examples', link: '/api-examples' }
// ]
}
},
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }
]
{ icon: "github", link: "https://git.polv.cc/polv/yt2press" },
],
},
markdown: {
image: {
lazyLoading: true,
},
config(md) {
// production-only gate
const isProd =
process.env.NODE_ENV === "production" ||
process.env.VITEPRESS_ENV === "production"; // extra safety
if (isProd) {
md.core.ruler.push("rewrite-image-urls", (state) => {
if (!state.tokens) return;
for (const token of state.tokens) {
if (token.type !== "inline") continue;
for (const child of token.children ?? []) {
// images: ![alt](src)
if (
child.type === "image" &&
typeof child.attrGet("src") === "string"
) {
const src = child.attrGet("src");
// rewrite only /images/* (adjust if your paths differ)
if (src && src.startsWith("/images/")) {
child.attrSet("src", `${IMG_ORIGIN}${src}`);
}
}
}
}
});
}
},
},
vite: {
clearScreen: false,
server: {
// make sure this port matches the devUrl port in tauri.conf.json file
port: 5173,
// Tauri expects a fixed port, fail if that port is not available
strictPort: true,
// if the host Tauri is expecting is set, use it
host: host || false,
watch: {
// tell vite to ignore watching `src-tauri`
ignored: ["**/src-tauri/**"],
},
proxy: {
'/socket': {
target: 'ws://localhost:8080',
"/socket": {
target: "ws://localhost:8080",
ws: true,
rewriteWsOrigin: true,
}
},
},
},
}
})
// Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`.
envPrefix: ["VITE_", "TAURI_ENV_*"],
build: {
// Tauri uses Chromium on Windows and WebKit on macOS and Linux
target:
process.env.TAURI_ENV_PLATFORM == "windows" ? "chrome105" : "safari13",
// don't minify for debug builds
minify: !process.env.TAURI_ENV_DEBUG ? "esbuild" : false,
// produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_ENV_DEBUG,
},
},
});
@@ -24,7 +24,7 @@ function onSubmit(ev: SubmitEvent) {
ev.preventDefault();
if (!q.value) return;
const src = "/" + q.value;
const src = "/" + encodeURIComponent(q.value);
const isSameSrc = videoSrc.value === src;
videoSrc.value = src;
+63 -9
View File
@@ -1,16 +1,29 @@
<template>
<Teleport to="body">
<video v-if="videoURL" controls :src="videoURL" ref="video">Hello</video>
<div :class="$style.container">
<YouTube ref="yt" v-if="youtubeID" :id="youtubeID" />
<video
v-else-if="videoURL"
controls
:src="videoURL"
ref="video"
@error="onVideoNotFound"
/>
</div>
</Teleport>
</template>
<script setup lang="ts">
import { useData } from "vitepress";
import { computed, useTemplateRef, watch } from "vue";
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from "vue";
import YouTube from "./YouTube.vue";
const { frontmatter } = useData<{ video?: string }>();
const videoURL = computed(() => frontmatter.value?.video);
const videoEl = useTemplateRef("video");
const ytEl = useTemplateRef("yt");
const youtubeID = ref("");
function setImgClick() {
document.removeEventListener("click", imgClickListener);
@@ -29,30 +42,71 @@ function imgClickListener(ev: PointerEvent) {
if (!(ev.target instanceof HTMLImageElement)) return;
const img = ev.target;
if (!videoEl.value) return;
const v = videoEl.value;
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
if (!t) return;
v.currentTime = t;
if (videoEl.value) {
videoEl.value.currentTime = t;
} else if (ytEl.value) {
ytEl.value.seekTo(t);
}
}
watch(videoURL, () => {
setImgClick();
});
setTimeout(() => setImgClick(), 500);
function onVideoNotFound() {
const m = /\[(.+?)\]\.\S+$/.exec(videoURL.value || "") || [];
youtubeID.value = m[1] || "";
}
function onOrientationChanged() {
if (window.screen.orientation.type.startsWith("landscape")) {
if (videoEl.value) {
videoEl.value.requestFullscreen();
return;
} else if (ytEl.value) {
ytEl.value.requestFullscreen();
return;
}
}
if (document.fullscreenElement) {
document.exitFullscreen();
}
}
onMounted(() => {
setTimeout(() => setImgClick(), 500);
if (window.screen?.orientation) {
window.screen.orientation.addEventListener("change", onOrientationChanged);
}
});
onBeforeUnmount(() => {
if (window.screen?.orientation) {
window.screen.orientation.removeEventListener("change", onOrientationChanged);
}
if (document.fullscreenElement) {
document.exitFullscreen();
}
});
</script>
<style scoped>
video {
<style module>
.container {
width: 400px;
overflow: visible;
position: fixed;
bottom: 10px;
left: 10px;
z-index: 100;
> * {
width: 100%;
}
}
</style>
@@ -0,0 +1,70 @@
<template>
<div :class="$style.container">
<iframe
id="yt-player"
ref="iframe"
:class="$style.iframe"
width="100%"
height="100%"
:src="url.href"
frameborder="0"
allow="
accelerometer;
autoplay;
encrypted-media;
gyroscope;
picture-in-picture;
fullscreen;
"
>
</iframe>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, useTemplateRef } from "vue";
const props = defineProps<{ id: string; title?: string }>();
defineExpose({ seekTo, requestFullscreen });
const url = new URL("https://www.youtube.com/embed/" + props.id);
url.searchParams.set("enablejsapi", "1");
const player = ref();
const iframe = useTemplateRef("iframe");
onMounted(() => {
const { YT } = window as any;
if (YT?.Player && iframe.value) {
player.value = new YT.Player(iframe.value);
}
});
function seekTo(t: number) {
if (player.value) {
player.value.seekTo(t, true);
}
}
function requestFullscreen() {
if (iframe.value) {
iframe.value.requestFullscreen();
}
}
</script>
<style module>
.container {
padding-bottom: 56.25%;
position: relative;
}
.iframe {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
</style>
+6
View File
@@ -0,0 +1,6 @@
/* body {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
} */
+2
View File
@@ -1,3 +1,5 @@
import "./custom.css";
import type { Theme } from "vitepress";
import DefaultTheme from "vitepress/theme";
import { h } from 'vue'
+19 -8
View File
@@ -1,5 +1,6 @@
import { type Plugin, type ViteDevServer } from "vite";
import { readFileSync, mkdirSync, writeFileSync } from "fs";
import sharp from "sharp";
export default function ytParsePlugin(): Plugin {
return {
@@ -8,19 +9,22 @@ export default function ytParsePlugin(): Plugin {
server.ws.on("download-q", ({ q }) => {
try {
mkdirSync(`docs/${q}`);
mkdirSync(`docs/public/images/${q}`);
} catch (e) {}
let outMd = "";
const re = /^(?<min>\d{1,2}):(?<sec>\d{2})\s*$/;
for (const line of readFileSync(`docs/${q}.md`, "utf-8").trimEnd().split("\n")) {
for (const line of readFileSync(`docs/${q}.md`, "utf-8")
.trimEnd()
.split("\n")) {
const m = re.exec(line);
if (m) {
const { min, sec } = m.groups!;
const t = parseInt(min) * 60 + parseInt(sec);
server.ws.send("seek-q", { t });
outMd += `[${line}](./${q}/${t}.png)`;
outMd += `[${line}](/images/${q}/${t}.webp)`;
} else {
outMd += line + "\n";
}
@@ -30,12 +34,19 @@ export default function ytParsePlugin(): Plugin {
});
server.ws.on("timed-q", ({ q, t, data }) => {
writeFileSync(
`docs/${q}/${t}.png`,
data.replace(/^data:image\/png;base64,/, ""),
"base64",
);
sharp(
Buffer.from(data.replace(/^data:image\/png;base64,/, ""), "base64"),
)
.rotate()
.resize({
width: 800,
height: 600,
fit: "inside",
withoutEnlargement: true,
})
.webp({ quality: 75 })
.toFile(`docs/public/images/${q}/${t}.png`);
});
},
};
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+21
View File
@@ -9,6 +9,27 @@ hero:
<Downloader />
- [HTC三次押中科技革命,為何三次都替別人賺了大錢?|從台灣股王到被Google兩度帶走核心團隊](./HTC三次押中科技革命,為何三次都替別人賺了大錢?|從台灣股王到被Google兩度帶走核心團隊.md)
- [茅台最怕的,不是競爭對手,而是中國年輕人!曾經一瓶難求的白酒,神話還能撐多久?](./茅台最怕的,不是競爭對手,而是中國年輕人!曾經一瓶難求的白酒,神話還能撐多久?.md)
- [沃爾瑪抄走一切,為什麼還是打不過好市多?Costco 最反常識的商業秘密!](./沃爾瑪抄走一切,為什麼還是打不過好市多?Costco_最反常識的商業秘密!.md)
- [辛拉麵背後:財閥、媒體與國家,如何一步步設計你的泡麵選擇](./辛拉麵背後:財閥、媒體與國家,如何一步步設計你的泡麵選擇.md)
- [一家輪胎公司,為什麼能決定全世界廚師的命運?|米其林:一本虧錢百年的生死簿](./一家輪胎公司,為什麼能決定全世界廚師的命運?|米其林:一本虧錢百年的生死簿.md)
- [日清差點把杯麵做死,卻被一場持槍劫案救活|一杯泡麵如何賣遍全球?](./日清差點把杯麵做死,卻被一場持槍劫案救活|一杯泡麵如何賣遍全球?.md)
- [柯達破產14年后,竟靠一件T恤還魂,年入10億美金...](./柯達破產14年后,竟靠一件T恤還魂,年入10億美金.md)
- [別再把紅牛當飲料公司!它如何靠「玩命運動」,一年賣出140億罐?](./別再把紅牛當飲料公司!它如何靠「玩命運動」,一年賣出140億罐?.md)
- [一家馬桶公司,為什麼成了AI命脈?TOTO埋了50年的暗棋](./一家馬桶公司,為什麼成了AI命脈?TOTO埋了50年的暗棋.md)
- [樂高差點被「創新」害死:最後救它的,竟是一雙舊球鞋!](./樂高差點被「創新」害死:最後救它的,竟是一雙舊球鞋!.md)
- [錯過NVIDIA了?Anthropic可能是下一個改變你財富命運的AI巨頭](./錯過NVIDIA了?Anthropic可能是下一個改變你財富命運的AI巨頭.md)
- [長榮帝國締造者張榮發:算準了世界,為何算錯了自己的人生?](./長榮帝國締造者張榮發:算準了世界,為何算錯了自己的人生?.md)
- [不准離婚、不准婚外情:李錦記靠一部狠到離譜的家法,打破「富不過三代」!](./不准離婚、不准婚外情:李錦記靠一部狠到離譜的家法,打破「富不過三代」!.md)
- [誠品自食其果?養肥黃金地段18年,反被房東掃地出門....](./誠品自食其果?養肥黃金地段18年,反被房東掃地出門.....md)
- [Shein帝国:廉价时尚背后的惊人代价|许仰天|婚纱网店](./Shein帝国:廉价时尚背后的惊人代价|许仰天|婚纱网店.md)
- [【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ](./【2026年最新版】タイ入国前に必ず見て!入国前・入国審査・入国後の注意事項まとめ.md)
- [比西藏、新疆、蒙古近 【韓國為啥不是中國的?】文化最像 卻沒被併吞?](./比西藏、新疆、蒙古近_【韓國為啥不是中國的?】文化最像_卻沒被併吞?.md)
- [泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?](./泰國為什麼掉隊了?越南、大馬、印尼都在搶產業,曼谷還能翻身嗎?.md)
- [39年招牌走入歷史!統一砸290億買家樂福又改名、入股Lopia,跟量販店危機有關?【懂商業看商周】Ep.138](./39年招牌走入歷史!統一砸290億買家樂福又改名、入股Lopia,跟量販店危機有關?【懂商業看商周】Ep.138.md)
- [Airbnb 泡沫化危機!各國政府聯手「下架」,房產投資者的惡夢來了?](./Airbnb_泡沫化危機!各國政府聯手「下架」,房產投資者的惡夢來了?.md)
- [曾統治全球99%電腦,為何死於一封公開信?賈伯斯當年手撕 Flash 的背後,隱藏著多恐怖的商戰陰謀!](./曾統治全球99_電腦,為何死於一封公開信?賈伯斯當年手撕_Flash_的背後,隱藏著多恐怖的商戰陰謀!.md)
- [緬甸為何痛恨羅興亞人? 佛教恐怖份子的誕生](./緬甸為何痛恨羅興亞人?_佛教恐怖份子的誕生.md)
- [走进普拉博沃时代的印度尼西亚 Prabowo’s first year: redefining Indonesia’s future | 世界大解说](./走进普拉博沃时代的印度尼西亚_Prabowo’s_first_year:_redefining_Indonesia’s_future_|_世界大解说.md)
- [东非最发达的城市现在怎么样了?揭秘肯尼亚不为人知的一面](./东非最发达的城市现在怎么样了?揭秘肯尼亚不为人知的一面.md)
+1 -1
View File
@@ -1,3 +1,3 @@
*
/*.*
!.gitignore
!README.md
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Loaded 100 of 24803 files, more files were not shown because too many files have changed in this diff. Show more